--- name: security-audit description: Security audit for web applications and servers. Identifies vulnerabilities, misconfigurations, and provides hardening recommendations. Use when user mentions "security audit", "auditoria segurança", "vulnerabilities", "security scan", "penetration test". author: Descomplicar® Crescimento Digital version: 2.0.0 quality_score: 75 user_invocable: true desk_task: 1480 allowed-tools: Glob --- # /security-audit - Security Compliance Specialist Auditoria de segurança seguindo padrões OWASP Top 10, GDPR e best practices Descomplicar®. --- ## Quando Usar - Auditar código para vulnerabilidades - Verificar configurações de segurança servidor - Avaliar compliance GDPR/ISO - Security review de aplicações - Análise de logs de segurança - Pentest básico (ethical hacking) - Hardening de servidor/aplicação --- ## Protocolo Obrigatório ### 1. Pesquisa Inicial (SEMPRE) ```javascript // Antes de qualquer audit, consultar histórico await mcp__memory-supabase__search_memories({ query: "security vulnerabilidade [sistema/projecto]", limit: 5 }); await mcp__wikijs__search_pages({ query: "security policy compliance" }); ``` ### 2. Verificar Contexto - [ ] Vulnerabilidades anteriores no sistema - [ ] Incidentes de segurança passados - [ ] Políticas de segurança existentes - [ ] Compliance requirements (GDPR, ISO, etc.) - [ ] Stack tecnológico e versões --- ## OWASP Top 10 (Checklist Obrigatória) ### A01 - Broken Access Control **Verificações:** ```php // ❌ VULNERÁVEL if ($_GET['user_id']) { $user = getUserById($_GET['user_id']); // Sem verificação ownership showUserData($user); } // ✅ SEGURO if ($_GET['user_id']) { $user = getUserById($_GET['user_id']); if ($user->id !== $currentUser->id && !$currentUser->isAdmin()) { die('Unauthorized'); } showUserData($user); } ``` **Testes:** - [ ] Tentar aceder recurso de outro user (`/user/123` → `/user/124`) - [ ] Testar IDOR (Insecure Direct Object Reference) - [ ] Verificar se RBAC implementado correctamente - [ ] Path traversal (`../../../etc/passwd`) - [ ] Forced browsing (aceder `/admin` sem autenticação) ### A02 - Cryptographic Failures **Verificações:** ```php // ❌ VULNERÁVEL $password = md5($_POST['password']); // MD5 é inseguro // ✅ SEGURO $password = password_hash($_POST['password'], PASSWORD_BCRYPT); ``` **Checklist:** - [ ] Passwords com bcrypt/argon2 (não MD5/SHA1) - [ ] Dados sensíveis encriptados em BD - [ ] HTTPS em produção (não HTTP) - [ ] Cookies com flags `Secure` e `HttpOnly` - [ ] Sem PII em logs **Testes:** ```bash # Verificar HTTPS curl -I https://site.com | grep -i "strict-transport-security" # Verificar cookies curl -I https://site.com | grep -i "set-cookie" # Deve ter: Secure; HttpOnly; SameSite=Strict ``` ### A03 - Injection (SQL, Command, LDAP) **Verificações SQL Injection:** ```php // ❌ VULNERÁVEL $sql = "SELECT * FROM users WHERE id = " . $_GET['id']; // ✅ SEGURO (Prepared Statements) $stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?"); $stmt->execute([$_GET['id']]); ``` **Testes:** ```sql -- Payloads comuns ' OR '1'='1 '; DROP TABLE users; -- ' UNION SELECT NULL, NULL, NULL-- ``` **Command Injection:** ```php // ❌ VULNERÁVEL system("ping " . $_GET['host']); // ✅ SEGURO $host = escapeshellarg($_GET['host']); system("ping $host"); ``` **Checklist:** - [ ] Prepared statements em todas as queries - [ ] Input sanitizado antes de shell commands - [ ] NoSQL injection prevenido (MongoDB, etc.) - [ ] LDAP injection prevenido - [ ] Template injection prevenido (Twig, Smarty) ### A04 - Insecure Design **Verificações:** - [ ] Rate limiting implementado (login, API) - [ ] CAPTCHA em formulários públicos - [ ] MFA disponível para contas admin - [ ] Session timeout configurado - [ ] Password policy forte (min 8 chars, uppercase, etc.) **Testes:** ```bash # Testar rate limiting for i in {1..100}; do curl -X POST https://site.com/login \ -d "email=test@test.com&password=wrong" & done # Deve bloquear após N tentativas ``` ### A05 - Security Misconfiguration **Checklist Servidor:** ```bash # Verificar versões expostas curl -I https://site.com | grep -i "server:" # Não deve revelar Apache/2.4.41 ou PHP/8.1.2 # Verificar directory listing curl https://site.com/uploads/ # Não deve listar ficheiros # Verificar ficheiros sensíveis expostos curl https://site.com/.env curl https://site.com/.git/config curl https://site.com/phpinfo.php # Todos devem dar 403/404 ``` **Headers de Segurança:** ```bash # Verificar headers obrigatórios curl -I https://site.com | grep -E "X-Frame-Options|X-Content-Type-Options|Content-Security-Policy|Strict-Transport-Security" ``` **Configuração Correcta:** ```nginx # Nginx - Security Headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Content-Security-Policy "default-src 'self' https:; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'" always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # Desactivar server tokens server_tokens off; ``` ### A06 - Vulnerable and Outdated Components **Verificações:** ```bash # PHP - Composer composer audit # Node.js npm audit # WordPress wp core version wp plugin list --format=json | jq '.[] | select(.update=="available")' # Verificar CVEs conhecidos curl https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=wordpress+plugin+NAME ``` **Checklist:** - [ ] Dependências actualizadas (últimos 3 meses) - [ ] Sem bibliotecas com vulnerabilidades conhecidas - [ ] PHP/Node/Python versão suportada - [ ] WordPress core e plugins actualizados ### A07 - Identification and Authentication Failures **Verificações:** ```php // ❌ VULNERÁVEL - Session Fixation session_start(); // ✅ SEGURO session_start(); session_regenerate_id(true); // Regenerar após login ``` **Checklist:** - [ ] Session regenerate após login - [ ] Logout invalida sessão no servidor - [ ] Session timeout (15-30 min) - [ ] Password reset com token expirável - [ ] Account lockout após N tentativas falhadas - [ ] Sem user enum (login não revela se user existe) **Testes:** ```bash # Testar user enumeration curl -X POST https://site.com/login \ -d "email=naoexiste@test.com&password=wrong" # Não deve dizer "user não existe" # Testar session fixation # 1. Obter PHPSESSID # 2. Fazer login # 3. Verificar se PHPSESSID mudou (deve mudar) ``` ### A08 - Software and Data Integrity Failures **Verificações:** ```php // ❌ VULNERÁVEL - Insecure Deserialization $data = unserialize($_GET['data']); // ✅ SEGURO $data = json_decode($_GET['data'], true); ``` **Checklist:** - [ ] Evitar `unserialize()` de input user - [ ] Verificar integridade de updates (signatures) - [ ] CI/CD com verificação de dependências - [ ] Subresource Integrity (SRI) em CDNs **SRI Example:** ```html ``` ### A09 - Security Logging and Monitoring Failures **Checklist:** - [ ] Login attempts logged (success/fail) - [ ] Access to sensitive data logged - [ ] Input validation failures logged - [ ] Logs não contêm passwords ou PII - [ ] Alertas configurados para actividade suspeita - [ ] Retenção de logs (mínimo 90 dias) **Logs Essenciais:** ```bash # Nginx access log tail -f /var/log/nginx/access.log # PHP error log tail -f /var/log/php/error.log # MySQL slow query log tail -f /var/log/mysql/slow.log # Fail2ban log tail -f /var/log/fail2ban.log ``` **Análise de Logs:** ```bash # Tentativas de SQL injection grep -i "union.*select" /var/log/nginx/access.log # Tentativas de path traversal grep -E "\.\./|\.\.%2F" /var/log/nginx/access.log # Scans de vulnerabilidades grep -E "nikto|nmap|sqlmap" /var/log/nginx/access.log # Tentativas de login falhadas grep "Failed password" /var/log/secure ``` ### A10 - Server-Side Request Forgery (SSRF) **Verificações:** ```php // ❌ VULNERÁVEL $url = $_GET['url']; file_get_contents($url); // Pode aceder rede interna // ✅ SEGURO $url = $_GET['url']; $parsed = parse_url($url); if ($parsed['host'] !== 'allowed-domain.com') { die('Invalid URL'); } // Whitelist de domínios permitidos ``` **Testes:** ```bash # Tentar aceder localhost curl "https://site.com/fetch?url=http://localhost/admin" # Tentar aceder rede interna curl "https://site.com/fetch?url=http://192.168.1.1" ``` --- ## Severidade de Findings ``` 🔴 CRÍTICO (Score 9-10) Exploração imediata possível, dados em risco RCE, SQL Injection, Authentication Bypass → Corrigir IMEDIATAMENTE (<24h) 🟠 ALTO (Score 7-8.9) Vulnerabilidade significativa XSS Stored, CSRF, Insecure Deserialization → Corrigir em 24-48h 🟡 MÉDIO (Score 4-6.9) Risco moderado XSS Reflected, Information Disclosure, Missing Headers → Corrigir em 7 dias 🟢 BAIXO (Score 1-3.9) Melhoria recomendada Weak Password Policy, Verbose Errors, Outdated Libraries → Corrigir em 30 dias ``` **Cálculo CVSS v3:** https://www.first.org/cvss/calculator/3.1 --- ## Template Relatório de Segurança ```markdown # 🔒 RELATÓRIO DE SEGURANÇA **Sistema:** [Nome do Sistema/Aplicação] **Data:** [YYYY-MM-DD] **Auditor:** Security Compliance Specialist - Descomplicar® **Scope:** [Frontend | Backend | Infra | Full Stack] --- ## EXECUTIVE SUMMARY [2-3 parágrafos resumindo estado de segurança global] **Score Global:** [X]/100 **CVSS Médio:** [X.X] **Breakdown:** - 🔴 Críticos: [N] findings - 🟠 Altos: [N] findings - 🟡 Médios: [N] findings - 🟢 Baixos: [N] findings --- ## FINDINGS ### 🔴 CRÍTICOS ([N] findings) #### FINDING-001: SQL Injection em Login - **Severidade:** CRÍTICO (CVSS 9.8) - **Componente:** `login.php` linha 45 - **Categoria OWASP:** A03 - Injection **Descrição:** Parâmetro `username` não sanitizado, permitindo SQL injection. **Evidência:** ```php // Código vulnerável (login.php:45) $sql = "SELECT * FROM users WHERE username = '" . $_POST['username'] . "'"; ``` **Proof of Concept:** ```bash curl -X POST https://site.com/login \ -d "username=' OR '1'='1&password=anything" # Resultado: acesso sem password ``` **Impacto:** - Acesso total à base de dados - Bypass de autenticação - Exfiltração de dados de clientes - Possível RCE via `INTO OUTFILE` **Remediação:** ```php // Usar prepared statements $stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?"); $stmt->execute([$_POST['username']]); ``` **Prazo:** IMEDIATO (fix em produção hoje) **Status:** 🔴 OPEN --- ### 🟠 ALTOS ([N] findings) #### FINDING-002: XSS Stored em Comentários - **Severidade:** ALTO (CVSS 7.2) - **Componente:** `comments.php` - **Categoria OWASP:** A03 - Injection (XSS) **Descrição:** Input de comentários não escapa output, permitindo XSS persistente. **Evidência:** ```html