Files
Emanuel Almeida 6b3a6f2698 feat: refactor 30+ skills to Anthropic progressive disclosure pattern
- All SKILL.md files now <500 lines (avg reduction 69%)
- Detailed content extracted to references/ subdirectories
- Frontmatter standardised: only name + description (Anthropic standard)
- New skills: brand-guidelines, spec-coauthor, report-templates, skill-creator
- Design skills: anti-slop guidelines, premium-proposals reference
- Removed non-standard frontmatter fields (triggers, version, author, category)

Plugins affected: infraestrutura, marketing, dev-tools, crm-ops, gestao,
core-tools, negocio, perfex-dev, wordpress, design-media

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 15:05:03 +00:00

6.1 KiB

/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:

// ❌ 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:

// ❌ 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:

# 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:

// ❌ 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:

// ❌ 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:

# 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:

# 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:

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:

# 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:

// ❌ 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:

# 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:

// ❌ VULNERÁVEL
$data = unserialize($_GET['data']);

// ✅ SEGURO
$data = json_decode($_GET['data'], true);

SRI Example:

<script src="https://cdn.example.com/lib.js"
        integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/ux..."
        crossorigin="anonymous"></script>

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:

# 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:

// ❌ 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:

curl "https://site.com/fetch?url=http://localhost/admin"
curl "https://site.com/fetch?url=http://192.168.1.1"