Testes ofensivos: O dia em que o pipeline aprovou uma vulnerabilidade.
- #Automação
- #Continuous Integration/Continuous Delivery (CI/CD)
- #QA
- #Segurança da Informação
Imagine a cena: o time de desenvolvimento comemora mais uma entrega bem-sucedida.
Todos os testes passaram no pipeline. O CI/CD brilhou em verde.
O deploy foi feito com sucesso.
Dias depois… começam as ligações. O sistema foi invadido.
Dados sensíveis vazaram.
O que aconteceu?
O pipeline — aquele guardião incansável que só aprova código impecável — deixou passar uma vulnerabilidade crítica.
O falso conforto do “Tudo Verde”
O verde no pipeline é sedutor.
Ele transmite a sensação de que tudo está sob controle: "Seu código está seguro, siga em frente".
Mas pipelines comuns foram criados para garantir funcionalidade, não segurança.
Isso significa que:
- ✅ Testes unitários confirmaram que funções funcionam.
- ✅ Testes de integração garantiram que os módulos se comunicam.
- ✅ Testes de interface verificaram que o usuário consegue navegar.
Mas nenhum deles perguntou:
“E se alguém tentar fazer algo que não deveria ?”
O ataque que ninguém testou:
O sistema tinha um endpoint que retornava informações de um cliente a partir do seu ID numérico:
GET /cliente/123
Se o cliente existisse, retornava:
json
{
"id": 123,
"nome": "João da Silva",
"email": "joao@email.com"
}
O problema
O código SQL por trás dessa rota era construído assim:
SELECT * FROM clientes WHERE id = '123';
Sem validação ou parametrização. Isso significa que qualquer valor colocado no lugar de 123
seria inserido diretamente na consulta.
O que o invasor fez
O atacante testou:
GET /cliente/123 OR 1=1
Essa simples alteração transformou a consulta em:
sql
SELECT * FROM clientes WHERE id = '123' OR 1=1;
A expressão 1=1
sempre é verdadeira, então o banco retornou todos os clientes.
Em segundos, o invasor tinha acesso a informações confidenciais de toda a base.
Por que o pipeline não detectou isso?
- Testes só cobriam o “caminho feliz” — verificavam apenas IDs válidos.
- Sem testes negativos — não havia cenários simulando ataques.
- Nenhum scanner de segurança — ferramentas como OWASP ZAP, Trivy ou Bandit não estavam integradas.
- Cobertura de código enganosa — 90% de cobertura não significa 90% de segurança.
Como blindar seu pipeline
Se você quer que seu CI/CD seja um verdadeiro guardião contra vulnerabilidades, inclua:
- Testes negativos: validar o que não deve ser possível.
- Testes de permissão: garantir que cada usuário só acesse o que tem direito.
- Ferramentas automáticas de segurança:
- OWASP ZAP (testes dinâmicos)
- Trivy (scan de containers e dependências)
- Bandit (análise estática para Python)
- Auditorias manuais periódicas — criatividade maliciosa ainda é humana.
Pipeline de exemplo com segurança
yaml
name: CI Security Example
on: [push]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Instalar dependências
run: npm install
- name: Rodar testes unitários
run: npm test
- name: Análise de vulnerabilidades com Trivy
uses: aquasecurity/trivy-action@master
with:
scan-type: fs
ignore-unfixed: true
vuln-type: 'os,library'
- name: Scan OWASP ZAP
uses: zaproxy/action-baseline@v0.7.0
with:
target: 'http://localhost:3000'
Conclusão
Pipelines CI/CD não garantem segurança por padrão.
Eles só sabem o que foi ensinado a verificar.
Se você não ensinar o pipeline a procurar por vulnerabilidades, ele vai aprovar código inseguro todos os dias — e você talvez nem perceba.
O “dia em que o pipeline aprovou uma vulnerabilidade” não precisa acontecer no seu time.
Mas, para isso, é preciso mudar o mindset: "não basta testar se funciona — é preciso testar se não abre brechas de segurança."