# /security-audit - OWASP Top 10 Checklist Detalhada Verificações e exemplos de código para cada categoria OWASP Top 10. ## 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) **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:** ```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 - [ ] LDAP injection prevenido - [ ] Template injection prevenido (Twig, Smarty) --- ## A04 - Insecure Design **Checklist:** - [ ] 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/ # 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:** ```nginx 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; 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")' ``` **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" ``` --- ## A08 - Software and Data Integrity Failures **Verificações:** ```php // ❌ VULNERÁVEL $data = unserialize($_GET['data']); // ✅ SEGURO $data = json_decode($_GET['data'], true); ``` **SRI Example:** ```html ``` --- ## A09 - Security Logging and Monitoring Failures **Checklist:** - [ ] Login attempts logged (success/fail) - [ ] Access to sensitive data logged - [ ] Logs não contêm passwords ou PII - [ ] Alertas configurados para actividade suspeita - [ ] Retenção de logs (mínimo 90 dias) **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 curl "https://site.com/fetch?url=http://localhost/admin" curl "https://site.com/fetch?url=http://192.168.1.1" ```