<h2>SAST e DAST: Fundamentos e Diferenças</h2>
<p>A segurança de aplicações é um dos pilares mais críticos do desenvolvimento moderno. Existem duas abordagens fundamentais para identificar vulnerabilidades: SAST (Static Application Security Testing) e DAST (Dynamic Application Security Testing). Compreender a diferença entre elas é essencial para construir uma estratégia de segurança eficaz em seus pipelines de CI/CD.</p>
<p>SAST analisa o código-fonte, bytecode ou binários sem executar a aplicação. É como revisar um livro antes de publicá-lo, procurando por erros estruturais. DAST, por outro lado, testa a aplicação em execução, simulando ataques reais contra a aplicação rodando. É como testar um carro em uma pista, verificando como ele se comporta sob pressão. Ambas são complementares: SAST encontra problemas cedo no desenvolvimento, enquanto DAST identifica vulnerabilidades que só aparecem em tempo de execução ou em contextos específicos de produção.</p>
<p>A integração de ambas em pipelines de CI/CD cria uma camada dupla de proteção. Você consegue bloquear código vulnerável antes mesmo de fazer deploy, e também valida a segurança da aplicação já rodando. Neste artigo, vamos explorar as ferramentas mais populares e como integrá-las adequadamente.</p>
<h2>Trivy: SAST Leve e Focado em Containers</h2>
<p>O Trivy é uma ferramenta SAST desenvolvida pela Aqua Security que se destacou por sua leveza e velocidade. Ela foi projetada originalmente para varrer imagens de container, mas evoluiu para detectar vulnerabilidades em código-fonte, dependências e configurações. A grande vantagem do Trivy é a simplicidade: ele funciona com um único comando e integra perfeitamente em qualquer pipeline.</p>
<p>O Trivy mantém um banco de dados local de vulnerabilidades conhecidas (CVEs) que é atualizado automaticamente. Ele consegue identificar problemas em dependências do Python, Node.js, Go, Java e muitas outras linguagens. Para começar, basta instalar e executar:</p>
<pre><code class="language-bash"># Instalação no Ubuntu/Debian
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | apt-key add - echo "deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | tee -a /etc/apt/sources.list.d/trivy.list
apt-get update && apt-get install trivy
Escanear um repositório local
trivy fs --severity HIGH,CRITICAL ./seu-projeto
Escanear uma imagem Docker
trivy image nginx:latest
Gerar relatório em JSON para integração
trivy fs --format json --output results.json ./seu-projeto</code></pre>
<p>A integração em um pipeline GitLab CI/CD é direta:</p>
<pre><code class="language-yaml"># .gitlab-ci.yml
stages:
- security
trivy-scan:
stage: security
image: aquasec/trivy:latest
script:
- trivy fs --severity HIGH,CRITICAL --exit-code 1 .
artifacts:
reports:
sast: trivy-results.json
when: always</code></pre>
<p>O <code>--exit-code 1</code> força a falha do job se vulnerabilidades críticas ou altas forem encontradas. Isso impede que código vulnerável chegue ao repositório principal. Você pode ajustar o nível de severidade conforme sua política de segurança. O Trivy também suporta análise de secrets (senhas expostas), o que é particularmente útil para evitar credenciais no repositório.</p>
<h2>SonarQube: SAST Profundo com Qualidade de Código</h2>
<p>O SonarQube é uma plataforma enterprise de análise de código que vai além de segurança. Ele combina SAST com análise de qualidade de código, identificando bugs, code smells, duplicações e vulnerabilidades. É especialmente poderoso para projetos grandes onde você precisa manter controle sobre múltiplos aspectos da qualidade.</p>
<p>SonarQube funciona em modo cliente-servidor. Você executa um scanner que envia os resultados para um servidor central, que processa e exibe os dados em um dashboard. A cobertura de linguagens é impressionante: Java, Python, JavaScript, C#, C++, Go, PHP, Swift, Kotlin e muitas outras. Para vulnerabilidades de segurança, o SonarQube usa regras que cobrem o OWASP Top 10 e CWE (Common Weakness Enumeration).</p>
<p>Configurar o SonarQube envolve dois passos: instalar o servidor e configurar o scanner em seu pipeline. Para começar com Docker:</p>
<pre><code class="language-bash"># Iniciar servidor SonarQube (versão community)
docker run -d --name sonarqube \
-p 9000:9000 \
sonarqube:latest
Acessar em http://localhost:9000 (usuário: admin, senha: admin)</code></pre>
<p>Agora, configure o scanner em seu projeto. Primeiro, instale o SonarScanner:</p>
<pre><code class="language-bash"># Instalação do SonarScanner (macOS com Homebrew)
brew install sonar-scanner
Ou no Linux, baixe a versão apropriada
wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.8.0.2856-linux.zip
unzip sonar-scanner-cli-4.8.0.2856-linux.zip</code></pre>
<p>Crie um arquivo <code>sonar-project.properties</code> na raiz do projeto:</p>
<pre><code class="language-properties">sonar.projectKey=meu-app
sonar.projectName=Minha Aplicação
sonar.projectVersion=1.0.0
sonar.sources=src
sonar.exclusions=*/Test.java,/node_modules/
sonar.host.url=http://localhost:9000
sonar.login=seu_token_aqui</code></pre>
<p>Execute o scanner:</p>
<pre><code class="language-bash">sonar-scanner</code></pre>
<p>Para integração em GitHub Actions:</p>
<pre><code class="language-yaml">name: SonarQube Analysis
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
sonar:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: sonarsource/sonarqube-scan-action@master
env:
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- uses: sonarsource/sonarqube-quality-gate-action@master
timeout-minutes: 5
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}</code></pre>
<p>O SonarQube é particularmente útil quando você precisa de análise contínua e histórico de métricas. O dashboard mostra tendências de segurança e qualidade ao longo do tempo, facilitando decisões arquiteturais.</p>
<h2>OWASP ZAP: DAST Dinâmico e Interativo</h2>
<p>Enquanto SAST analisa código estático, OWASP ZAP (Zed Attack Proxy) é um DAST que testa a aplicação em execução. O ZAP simula ataques reais contra endpoints HTTP, verificando vulnerabilidades como SQL Injection, XSS, CSRF, insecurança em autenticação e muitos outros vetores que só aparecem quando a aplicação está rodando.</p>
<p>O ZAP funciona como um proxy man-in-the-middle (MITM), interceptando requisições e respostas. Ele pode fazer testes passivos (apenas observando tráfego) ou ativos (enviando payloads maliciosos para tentar explorar vulnerabilidades). O OWASP ZAP é gratuito e open-source, com suporte extenso da comunidade.</p>
<p>Existem dois modos principais de usar ZAP: modo GUI (para exploração manual) e modo CLI (para automação em pipelines). Para CI/CD, o modo CLI é mais apropriado. Instale o ZAP:</p>
<pre><code class="language-bash"># No Ubuntu/Debian
sudo apt-get install zaproxy
Ou via Docker (recomendado para pipelines)
docker run --rm -t owasp/zap2docker-stable zap-baseline.py -t http://seu-app.local</code></pre>
<p>Exemplo de teste baseline com Docker:</p>
<pre><code class="language-bash">#!/bin/bash
Script para DAST com ZAP
Inicia a aplicação em background
docker run -d --name app-test -p 8080:8080 seu-app:latest
Aguarda a aplicação ficar pronta
sleep 10
Executa ZAP baseline (menos agressivo, mais rápido)
docker run --rm --network host \
-v $(pwd):/zap/wrk:rw \
owasp/zap2docker-baseline:latest \
zap-baseline.py \
-t http://localhost:8080 \
-r report.html \
-J report.json
Para teste mais profundo, use zap-full-scan.py ao invés
Limpa
docker stop app-test
docker rm app-test
Valida resultados (falha se HIGH ou CRITICAL encontrado)
if grep -q '"risk":"High"' report.json || grep -q '"risk":"Critical"' report.json; then
exit 1
fi</code></pre>
<p>Integração em GitHub Actions com ZAP:</p>
<pre><code class="language-yaml">name: OWASP ZAP DAST
on:
push:
branches: [ main ]
schedule:
- cron: '0 2 0' # Executar às 2AM aos domingos
jobs:
zap-scan:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Start application
run: |
docker-compose -f docker-compose.test.yml up -d
sleep 15
- name: Run ZAP Scan
uses: zaproxy/action-baseline@v0.7.0
with:
target: 'http://localhost:8080'
rules_file_name: '.zap/rules.tsv'
cmd_options: '-a'
- name: Upload ZAP results
if: always()
uses: actions/upload-artifact@v3
with:
name: zap-report
path: report_html.html</code></pre>
<p>O ZAP é ideal para testes em ambientes de staging antes de produção. Você consegue detectar vulnerabilidades de lógica de negócio, autenticação quebrada e ataques específicos do contexto da aplicação.</p>
<h2>Snyk: SAST Especializado em Dependências</h2>
<p>O Snyk é uma plataforma focada em encontrar e corrigir vulnerabilidades em dependências e container images. Enquanto Trivy é mais genérico, Snyk oferece análise mais profunda de bibliotecas, com insights sobre severidade, exploitabilidade real e patches disponíveis. É particularmente forte em ecossistemas como npm, pip, Maven e Gemfile.</p>
<p>Snyk combina dados de múltiplas fontes de vulnerabilidades (NVD, GHSA, banco próprio) para oferecer um quadro mais completo. Além de identificar CVEs, o Snyk verifica se há patches disponíveis e sugere versões seguras imediatamente. A plataforma também integra com repositórios Git, oferecendo pull requests automáticos para patches de segurança.</p>
<p>Instale e configure o Snyk CLI:</p>
<pre><code class="language-bash"># Instalação via npm
npm install -g snyk
Autenticar com sua conta Snyk
snyk auth
Testar vulnerabilidades em um projeto
snyk test
Monitorar continuamente (cria webhook no Git)
snyk monitor
Testar apenas dependências diretas (excluindo transitivas)
snyk test --strict-out-of-sync=false</code></pre>
<p>Exemplo de uso em um projeto Python:</p>
<pre><code class="language-bash"># Criar um ambiente virtual
python -m venv venv
source venv/bin/activate
Instalar dependências
pip install -r requirements.txt
Testar com Snyk
snyk test --file=requirements.txt
Gerar relatório em JSON
snyk test --json > snyk-report.json</code></pre>
<p>Integração em GitHub Actions:</p>
<pre><code class="language-yaml">name: Snyk Security
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
snyk:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run Snyk to check for vulnerabilities
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high
- name: Upload results to Snyk
uses: snyk/actions/setup@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
run: snyk monitor</code></pre>
<p>Uma das melhores características do Snyk é a integração automática com repositórios. Você pode configurar Snyk para criar pull requests automaticamente quando patches estão disponíveis:</p>
<pre><code class="language-bash"># Criar token API no dashboard Snyk
Conectar repositório via https://app.snyk.io
Snyk gerará PRs automáticas quando:
- Novos patches forem lançados
- Novas vulnerabilidades forem descobertas
- Dependências transitivas forem atualizadas</code></pre>
<p>Snyk é especialmente valioso em ambientes com muitas dependências, onde gerenciar patches manualmente seria impraticável.</p>
<h2>Orquestração Integrada: Pipeline Completo</h2>
<p>Integrar SAST e DAST em um pipeline único garante cobertura completa. O ideal é executar SAST rapidamente (bloqueia código ruim antes) e DAST em um ambiente mais controlado (testa a aplicação rodando). Aqui está um exemplo realista de pipeline GitLab CI/CD que integra todas as ferramentas:</p>
<pre><code class="language-yaml"># .gitlab-ci.yml - Pipeline completo SAST + DAST
stages:
- build
- sast
- docker
- deploy-staging
- dast
- cleanup
variables:
REGISTRY: registry.gitlab.com
IMAGE_NAME: $REGISTRY/$CI_PROJECT_PATH
build:
stage: build
image: python:3.11
script:
- pip install -r requirements.txt
- python -m pytest tests/ --cov=src
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
trivy-fs:
stage: sast
image: aquasec/trivy:latest
script:
- trivy fs --severity HIGH,CRITICAL --format json --output trivy-fs.json .
- trivy fs --severity HIGH,CRITICAL .
artifacts:
reports:
sast: trivy-fs.json
when: always
sonarqube:
stage: sast
image: sonarsource/sonar-scanner-cli:latest
script:
- sonar-scanner
-Dsonar.projectKey=$CI_PROJECT_NAME
-Dsonar.sources=src
-Dsonar.host.url=$SONAR_HOST_URL
-Dsonar.login=$SONAR_TOKEN
only:
- merge_requests
- main
snyk-test:
stage: sast
image: snyk/snyk:python-3.11
script:
- snyk test --severity-threshold=high
env:
SNYK_TOKEN: $SNYK_TOKEN
allow_failure: true
docker-build:
stage: docker
image: docker:latest
services:
- docker:dind
script:
- docker build -t $IMAGE_NAME:$CI_COMMIT_SHA .
- docker tag $IMAGE_NAME:$CI_COMMIT_SHA $IMAGE_NAME:latest
- docker push $IMAGE_NAME:$CI_COMMIT_SHA
- docker push $IMAGE_NAME:latest
trivy-image:
stage: docker
image: aquasec/trivy:latest
script:
- trivy image --severity HIGH,CRITICAL --format json --output trivy-image.json $IMAGE_NAME:$CI_COMMIT_SHA
- trivy image --severity HIGH,CRITICAL $IMAGE_NAME:$CI_COMMIT_SHA
dependencies:
- docker-build
artifacts:
reports:
container_scanning: trivy-image.json
when: always
deploy-staging:
stage: deploy-staging
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/app app=$IMAGE_NAME:$CI_COMMIT_SHA -n staging
- kubectl rollout status deployment/app -n staging
environment:
name: staging
url: https://staging.seu-app.com
only:
- main
zap-baseline:
stage: dast
image: owasp/zap2docker-stable:latest
script:
- sleep 30 # Aguarda deploy estar ready
- zap-baseline.py
-t https://staging.seu-app.com
-r report.html
-J report.json
-a # Enable all scanners
artifacts:
paths:
- report.html
- report.json
reports:
sast: report.json
when: always
allow_failure: true
only:
- main
cleanup-staging:
stage: cleanup
script:
- echo "Cleanup stage"
when: always</code></pre>
<p>Este pipeline segue uma ordem lógica: primeiro valida o código (build + testes), depois executa SAST em paralelo (Trivy, SonarQube, Snyk), constrói a imagem Docker e a escaneia, deploya em staging, e finalmente executa DAST contra a aplicação rodando.</p>
<h2>Conclusão</h2>
<p>Você aprendeu que <strong>SAST e DAST são complementares, não substitutos</strong>. SAST (Trivy, SonarQube, Snyk) encontra problemas no código e dependências antes da execução, enquanto DAST (OWASP ZAP) testa vulnerabilidades em tempo de execução. A combinação delas em um pipeline CI/CD cria uma defesa em profundidade que bloqueia a maioria dos riscos de segurança.</p>
<p>A <strong>escolha de ferramentas deve considerar o contexto</strong>: Trivy é leve e rápido para verificações simples, SonarQube é enterprise com histórico e controle fino, Snyk é especializado em dependências com patches automáticos, e OWASP ZAP é essencial para validar comportamento em runtime. Um pipeline maduro integra todas, mas nem todas as organizações precisam de todas simultaneamente.</p>
<p>Por fim, <strong>segurança é um processo contínuo</strong>. As ferramentas apenas alertam; cabe aos desenvolvedores e arquitetos entender as vulnerabilidades reportadas, priorizar baseado em risco real (não apenas score CVSS), e manter dependências atualizadas. Automação é essencial, mas contexto humano é insubstituível.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://aquasecurity.github.io/trivy/" target="_blank" rel="noopener noreferrer">Aqua Security Trivy Documentation</a></li>
<li><a href="https://docs.sonarqube.org/latest/" target="_blank" rel="noopener noreferrer">SonarQube Official Documentation</a></li>
<li><a href="https://www.zaproxy.org/docs/desktop/" target="_blank" rel="noopener noreferrer">OWASP ZAP User Guide</a></li>
<li><a href="https://docs.snyk.io/snyk-cli" target="_blank" rel="noopener noreferrer">Snyk CLI Documentation</a></li>
<li><a href="https://owasp.org/Top10/" target="_blank" rel="noopener noreferrer">OWASP Top 10 2021</a></li>
</ul>
<p><!-- FIM --></p>