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>
This commit is contained in:
@@ -0,0 +1,275 @@
|
||||
# /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
|
||||
<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:**
|
||||
```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"
|
||||
```
|
||||
@@ -0,0 +1,237 @@
|
||||
# /security-audit - Template de Relatório e Ferramentas
|
||||
|
||||
## Template Relatório de Segurança
|
||||
|
||||
```markdown
|
||||
# RELATORIO DE SEGURANCA
|
||||
|
||||
**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
|
||||
|
||||
### CRITICOS ([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
|
||||
$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"
|
||||
```
|
||||
|
||||
**Impacto:**
|
||||
- Acesso total à base de dados
|
||||
- Bypass de autenticação
|
||||
- Exfiltração de dados de clientes
|
||||
|
||||
**Remediação:**
|
||||
```php
|
||||
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
|
||||
$stmt->execute([$_POST['username']]);
|
||||
```
|
||||
|
||||
**Prazo:** IMEDIATO
|
||||
**Status:** OPEN
|
||||
|
||||
---
|
||||
|
||||
## OWASP TOP 10 COMPLIANCE
|
||||
|
||||
| # | Categoria | Status | Findings |
|
||||
|---|-----------|--------|----------|
|
||||
| A01 | Broken Access Control | Parcial | 2 médios |
|
||||
| A02 | Cryptographic Failures | OK | 0 |
|
||||
| A03 | Injection | Falha | 1 crítico, 1 alto |
|
||||
| A04 | Insecure Design | Parcial | 1 médio |
|
||||
| A05 | Security Misconfiguration | Atenção | 3 altos |
|
||||
| A06 | Vulnerable Components | Parcial | 5 baixos |
|
||||
| A07 | Auth Failures | OK | 0 |
|
||||
| A08 | Data Integrity | OK | 0 |
|
||||
| A09 | Logging Failures | Parcial | 1 médio |
|
||||
| A10 | SSRF | OK | 0 |
|
||||
|
||||
---
|
||||
|
||||
## COMPLIANCE GDPR
|
||||
|
||||
- [ ] Consentimento explícito capturado
|
||||
- [ ] Direito ao esquecimento implementado
|
||||
- [ ] Portabilidade de dados possível
|
||||
- [ ] Retenção de dados definida
|
||||
- [ ] Encriptação de dados sensíveis
|
||||
- [ ] Logging de acessos activo
|
||||
|
||||
**Score GDPR:** 75/100 (Parcialmente Conforme)
|
||||
|
||||
---
|
||||
|
||||
**Confidencial - Descomplicar® Crescimento Digital**
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Checklist GDPR Completo
|
||||
|
||||
### Consentimento
|
||||
- [ ] Opt-in explícito (não pré-seleccionado)
|
||||
- [ ] Linguagem clara
|
||||
- [ ] Granular (newsletter ≠ tracking)
|
||||
- [ ] Fácil de retirar
|
||||
|
||||
### Direitos do Titular
|
||||
- [ ] Direito ao acesso (exportar dados)
|
||||
- [ ] Direito à rectificação (editar dados)
|
||||
- [ ] Direito ao esquecimento (delete account)
|
||||
- [ ] Direito à portabilidade (formato standard)
|
||||
- [ ] Direito à oposição (opt-out processing)
|
||||
|
||||
### Segurança
|
||||
- [ ] Encriptação em trânsito (HTTPS)
|
||||
- [ ] Encriptação em repouso (BD sensível)
|
||||
- [ ] Passwords com hash forte (bcrypt)
|
||||
- [ ] Logs de acesso a dados pessoais
|
||||
- [ ] Notificação de breach (<72h)
|
||||
|
||||
### Documentação
|
||||
- [ ] Privacy policy actualizada (última 12 meses)
|
||||
- [ ] Cookie policy clara
|
||||
- [ ] Terms of service
|
||||
- [ ] Data processing agreement (DPA)
|
||||
|
||||
---
|
||||
|
||||
## Ferramentas de Análise
|
||||
|
||||
### Análise Estática (SAST)
|
||||
|
||||
```bash
|
||||
# PHP - PHPStan
|
||||
phpstan analyse --level=max src/
|
||||
|
||||
# PHP - Psalm
|
||||
psalm --show-info=true
|
||||
|
||||
# PHP - Security Checker
|
||||
local-php-security-checker
|
||||
|
||||
# JavaScript - ESLint
|
||||
eslint --ext .js,.jsx src/
|
||||
|
||||
# Python - Bandit
|
||||
bandit -r project/
|
||||
```
|
||||
|
||||
### Análise Dinâmica (DAST)
|
||||
|
||||
```bash
|
||||
# OWASP ZAP (headless)
|
||||
zap-cli quick-scan -s all https://site.com
|
||||
|
||||
# Nikto
|
||||
nikto -h https://site.com
|
||||
|
||||
# SQLMap
|
||||
sqlmap -u "https://site.com/page?id=1" --batch
|
||||
|
||||
# Nmap
|
||||
nmap -sV -sC site.com
|
||||
|
||||
# WPScan (WordPress)
|
||||
wpscan --url https://site.com --api-token YOUR_TOKEN
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Hardening Checklist
|
||||
|
||||
### Sistema Operativo (Linux)
|
||||
- [ ] Firewall activo (iptables/firewalld)
|
||||
- [ ] SELinux/AppArmor activado
|
||||
- [ ] SSH com key-based auth (não password)
|
||||
- [ ] SSH não permite root login
|
||||
- [ ] Fail2ban instalado e configurado
|
||||
- [ ] Automatic security updates
|
||||
- [ ] Portas desnecessárias fechadas
|
||||
|
||||
### Web Server (Nginx/Apache)
|
||||
- [ ] Server tokens desactivado
|
||||
- [ ] Directory listing desactivado
|
||||
- [ ] Security headers configurados
|
||||
- [ ] SSL/TLS configurado (A+ SSL Labs)
|
||||
- [ ] Apenas TLS 1.2+ (não SSL, TLS 1.0, 1.1)
|
||||
- [ ] HTTP/2 activado
|
||||
|
||||
### PHP
|
||||
- [ ] `display_errors = Off` em produção
|
||||
- [ ] `expose_php = Off`
|
||||
- [ ] `open_basedir` configurado
|
||||
- [ ] `disable_functions` configurado
|
||||
- [ ] File uploads limitados
|
||||
- [ ] OPcache activado
|
||||
|
||||
### MySQL
|
||||
- [ ] Bind apenas localhost (se possível)
|
||||
- [ ] Root sem acesso remoto
|
||||
- [ ] Passwords fortes
|
||||
- [ ] `skip-name-resolve`
|
||||
- [ ] Slow query log activado
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
Reference in New Issue
Block a user