Autenticação quebrada: problemas e soluções
1. Introdução à Autenticação Quebrada
Autenticação quebrada refere-se a falhas na verificação da identidade de um usuário, permitindo que invasores assumam contas alheias ou acessem recursos restritos. Esse problema ocupa consistentemente posições de destaque no OWASP Top 10, pois é a porta de entrada para a maioria dos ataques cibernéticos. É crucial distinguir autenticação fraca (credenciais vulneráveis) de autorização inadequada (permissões incorretas após o login). Enquanto a primeira falha ocorre antes do acesso, a segunda acontece depois. Os impactos típicos incluem acesso não autorizado a dados sensíveis, roubo de identidade e violações de dados que podem custar milhões às organizações.
2. Problemas Comuns de Implementação
Senhas fracas e políticas inadequadas
Muitos sistemas ainda aceitam senhas como "123456" ou "admin". Políticas que não exigem complexidade mínima (maiúsculas, minúsculas, números e caracteres especiais) facilitam ataques de dicionário. O reuso de senhas entre sistemas amplifica o dano quando uma base é comprometida.
Exemplo de política fraca:
// Política que aceita senhas de 4 caracteres
if (senha.length < 4) {
return "Senha muito curta";
}
// Sem validação de complexidade
Credenciais padrão e hardcoded
Dispositivos e aplicações frequentemente mantêm senhas de fábrica (admin/admin) ou credenciais fixas no código-fonte. Um repositório público no GitHub pode expor senhas de banco de dados ou APIs.
Exemplo perigoso:
// Código com credencial hardcoded
const DB_PASSWORD = "senha123";
const API_KEY = "sk-abc123def456";
Falta de proteção contra força bruta
Sistemas sem rate limiting permitem que um invasor tente milhares de combinações por minuto. Sem bloqueio de contas após tentativas falhas, o ataque pode continuar indefinidamente.
3. Falhas no Gerenciamento de Sessão
Tokens de sessão previsíveis ou expostos
IDs de sessão gerados com funções como Math.random() ou baseados em timestamp são previsíveis. Quando expostos em URLs (ex: ?sessionid=123), podem ser capturados em logs ou referenciados por terceiros.
Exemplo vulnerável:
// Geração insegura de token de sessão
function gerarToken() {
return Math.random().toString(36).substring(2); // Previsível
}
Sessões sem expiração adequada
Timeouts de sessão de 24 horas ou mais são comuns em aplicações web. Ausência de logout efetivo (apenas fechar a aba do navegador) mantém a sessão ativa em computadores compartilhados.
Reutilização de tokens após logout
Muitas aplicações apenas removem o cookie do lado do cliente, mas mantêm a sessão ativa no servidor. Um invasor que capture o token antes do logout pode reutilizá-lo posteriormente.
4. Vulnerabilidades em Mecanismos de Recuperação
Perguntas de segurança fracas
"Qual o nome do seu primeiro animal de estimação?" ou "Qual sua cidade natal?" são informações frequentemente disponíveis em redes sociais. Respostas como "cachorro" podem ser adivinhadas em poucas tentativas.
Links de redefinição previsíveis
Tokens de reset baseados em timestamp ou sequenciais (ex: reset/1001, reset/1002) permitem que um invasor tente múltiplos IDs até encontrar um válido.
Exemplo de token previsível:
// Token baseado em timestamp
function gerarTokenReset() {
return "reset_" + Date.now(); // Previsível por ordem cronológica
}
Aceitação de tokens expirados ou reutilizados
Sistemas que não validam o ciclo de vida do token de reset permitem que tokens antigos ou já utilizados sejam reutilizados para redefinir senhas.
5. Soluções: Boas Práticas de Implementação
Políticas de senha robustas
Implemente hashing com algoritmos lentos e seguros como bcrypt, Argon2 ou PBKDF2. Nunca armazene senhas em texto puro ou com hashing rápido como MD5 ou SHA-1.
Exemplo seguro com bcrypt:
const bcrypt = require('bcrypt');
const saltRounds = 12;
async function hashSenha(senha) {
const hash = await bcrypt.hash(senha, saltRounds);
return hash;
}
async function verificarSenha(senha, hash) {
return await bcrypt.compare(senha, hash);
}
Rate limiting e bloqueio progressivo
Limite o número de tentativas por IP e por conta. Aplique delays exponenciais (1s, 2s, 4s, 8s) e bloqueie a conta após 5-10 tentativas falhas consecutivas.
Exemplo de rate limiting:
// Middleware de rate limiting (express-rate-limit)
const rateLimit = require('express-rate-limit');
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutos
max: 5, // 5 tentativas
message: "Muitas tentativas. Tente novamente em 15 minutos."
});
Autenticação multifator (MFA)
Implemente um segundo fator como TOTP (Google Authenticator) ou SMS. Mesmo que a senha seja comprometida, o invasor precisa do segundo fator.
Exemplo de geração TOTP:
const speakeasy = require('speakeasy');
const secret = speakeasy.generateSecret({ length: 20 });
// Gerar token
const token = speakeasy.totp({
secret: secret.base32,
encoding: 'base32'
});
// Verificar token
const verified = speakeasy.totp.verify({
secret: secret.base32,
encoding: 'base32',
token: tokenInput,
window: 1
});
6. Soluções: Gerenciamento Seguro de Sessão
Geração criptograficamente segura de tokens
Utilize crypto.randomBytes (Node.js) ou secrets.token_hex (Python) para gerar tokens imprevisíveis.
Exemplo seguro:
const crypto = require('crypto');
function gerarTokenSessao() {
return crypto.randomBytes(32).toString('hex'); // 64 caracteres hex
}
Configuração rigorosa de cookies
Defina atributos de segurança nos cookies de sessão: HttpOnly (inacessível via JavaScript), Secure (apenas HTTPS), SameSite=Strict (proteção contra CSRF) e expiração adequada.
Exemplo de configuração:
res.cookie('sessionId', token, {
httpOnly: true,
secure: true,
sameSite: 'strict',
maxAge: 30 * 60 * 1000 // 30 minutos
});
Invalidar sessões no logout e no servidor
No logout, destrua a sessão no servidor (remova do banco de dados ou cache) e limpe o cookie do cliente.
Exemplo de logout seguro:
async function logout(req, res) {
await Session.destroy({ where: { id: req.session.id } });
res.clearCookie('sessionId');
res.redirect('/login');
}
7. Ferramentas e Testes de Verificação
Ferramentas de análise estática
Utilize Semgrep, SonarQube ou GitHub CodeQL para detectar credenciais hardcoded, uso de hashing fraco e políticas de senha inadequadas no código-fonte.
Testes de penetração automatizados
Burp Suite Community Edition e OWASP ZAP podem realizar ataques de força bruta controlados e identificar falhas de rate limiting. O Hydra é útil para testar dicionários de senhas.
Checklist de revisão de código
- [ ] Senhas armazenadas com bcrypt/Argon2/PBKDF2?
- [ ] Rate limiting implementado no login?
- [ ] Tokens de sessão gerados com
crypto.randomBytes? - [ ] Cookies configurados com HttpOnly, Secure, SameSite?
- [ ] Logout invalida sessão no servidor?
- [ ] Tokens de reset expiram e são de uso único?
- [ ] MFA disponível para contas sensíveis?
8. Conclusão e Checklist Final
Autenticação quebrada continua sendo uma das vulnerabilidades mais exploradas porque muitos desenvolvedores subestimam sua complexidade. As soluções apresentadas — desde hashing robusto até gerenciamento seguro de sessão e MFA — formam uma defesa em camadas contra ataques comuns.
Checklist rápido para evitar autenticação quebrada
- Armazene senhas com Argon2 ou bcrypt — nunca em texto puro ou MD5/SHA-1.
- Implemente rate limiting — limite tentativas por IP e bloqueie contas após falhas.
- Gere tokens criptograficamente seguros — use
crypto.randomBytespara sessão e reset. - Configure cookies com HttpOnly, Secure e SameSite — previne roubo via XSS e CSRF.
- Invalide sessões no logout — destrua no servidor, não apenas no cliente.
Referências
- OWASP - Authentication Cheat Sheet — Guia completo com boas práticas de implementação de autenticação segura.
- OWASP - Session Management Cheat Sheet — Documentação oficial sobre gerenciamento seguro de sessões.
- NIST SP 800-63B - Digital Identity Guidelines — Padrões do NIST para autenticação, incluindo políticas de senha e MFA.
- OWASP Top 10:2021 - A07:2021 Identification and Authentication Failures — Descrição oficial da categoria no OWASP Top 10.
- Node.js Crypto Documentation — Documentação oficial da API crypto para geração segura de tokens e hashing.
- bcrypt npm package — Biblioteca para hashing de senhas com salt rounds configuráveis.
- OWASP ZAP - Zed Attack Proxy — Ferramenta gratuita de teste de penetração para identificar vulnerabilidades de autenticação.