OWASP Top 10: As Vulnerabilidades Mais Críticas Explicadas
O que é a OWASP Top 10?
A Open Web Application Security Project (OWASP) publica periodicamente a lista das 10 vulnerabilidades mais críticas em aplicações web. Conhecer essa lista é obrigação de qualquer desenvolvedor que escreve código para produção.
1. Broken Access Control
A mais comum e perigosa. Acontece quando usuários conseguem acessar recursos além do que deveriam.
Vulnerável:
// Busca qualquer pedido pelo ID — sem verificar o dono
app.get('/pedidos/:id', async (req, res) => {
const pedido = await db.pedidos.findById(req.params.id);
res.json(pedido);
});Corrigido:
app.get('/pedidos/:id', autenticar, async (req, res) => {
const pedido = await db.pedidos.findOne({
_id: req.params.id,
usuarioId: req.user.id // garante que é dono do pedido
});
if (!pedido) return res.status(404).json({ erro: 'Não encontrado' });
res.json(pedido);
});2. Cryptographic Failures
Senhas em texto puro, dados sensíveis não criptografados, uso de algoritmos fracos.
Nunca faça isso:
# MD5 é quebrado para senhas
import hashlib
senha_hash = hashlib.md5(senha.encode()).hexdigest()Correto:
import bcrypt
def hash_senha(senha: str) -> str:
salt = bcrypt.gensalt(rounds=12)
return bcrypt.hashpw(senha.encode(), salt).decode()
def verificar_senha(senha: str, hash: str) -> bool:
return bcrypt.checkpw(senha.encode(), hash.encode())3. Injection (SQL, NoSQL, Command)
# VULNERÁVEL — SQL Injection
cursor.execute(f"SELECT * FROM usuarios WHERE email = '{email}'")
# SEGURO — parâmetros preparados
cursor.execute("SELECT * FROM usuarios WHERE email = %s", (email,))Command Injection:
import subprocess
# VULNERÁVEL
subprocess.run(f"ping {host}", shell=True)
# SEGURO — nunca use shell=True com input externo
subprocess.run(["ping", "-c", "4", host], check=True)4. Insecure Design
Falhas arquiteturais que não podem ser corrigidas só com código:
- Rate limiting ausente em endpoints sensíveis
- Falta de restrição de tentativas de login
- Ausência de 2FA em operações críticas
5. Security Misconfiguration
// Nunca exponha stack traces em produção
app.use((err, req, res, next) => {
if (process.env.NODE_ENV === 'production') {
res.status(500).json({ erro: 'Erro interno' });
} else {
res.status(500).json({ erro: err.message, stack: err.stack });
}
});Headers de segurança obrigatórios:
import helmet from 'helmet';
app.use(helmet()); // configura ~12 headers de segurança automaticamente
6. Vulnerable Components
# Verifique dependências com vulnerabilidades conhecidas
npm audit
pip-auditUse Snyk, Dependabot ou similar para alertas automáticos.
7. Identification and Authentication Failures
from secrets import token_urlsafe
from datetime import datetime, timedelta
def criar_token_recuperacao(usuario_id: int) -> str:
token = token_urlsafe(32)
expira = datetime.utcnow() + timedelta(hours=1)
db.tokens.insert({
'token': hash_token(token),
'usuario_id': usuario_id,
'expira_em': expira,
'usado': False
})
return token8. Software and Data Integrity Failures
- Verifique assinaturas de pacotes (npm provenance, PyPI trusted publishers)
- Não serialize/deserialize dados não confiáveis com pickle ou eval
- Use Subresource Integrity (SRI) para CDNs
9. Security Logging and Monitoring Failures
import logging
logger = logging.getLogger('seguranca')
def login(email: str, senha: str, ip: str):
usuario = buscar_usuario(email)
if not usuario or not verificar_senha(senha, usuario.hash_senha):
logger.warning(f"Login falhou | email={email} | ip={ip}")
raise HTTPException(status_code=401, detail="Credenciais inválidas")
logger.info(f"Login OK | usuario_id={usuario.id} | ip={ip}")10. Server-Side Request Forgery (SSRF)
from urllib.parse import urlparse
import ipaddress
HOSTS_BLOQUEADOS = ['localhost', '169.254.169.254'] # AWS metadata
def validar_url_externa(url: str) -> bool:
parsed = urlparse(url)
if parsed.hostname in HOSTS_BLOQUEADOS:
return False
try:
ip = ipaddress.ip_address(parsed.hostname)
if ip.is_private or ip.is_loopback:
return False
except ValueError:
pass
return TrueConclusão
Segurança não é uma feature — é um requisito. Revisar o código com o OWASP Top 10 em mente antes de cada deploy é um hábito simples que evita incidentes graves.