Autenticação vs autorização: o endpoint que qualquer um pode chamar
Essas duas palavras soam parecidas, e é na diferença entre elas que vivem as violações reais.
- Autenticação é quem é você? — fazer login, provar identidade.
- Autorização é o que você tem permissão para fazer? — se este usuário logado pode realizar esta ação sobre estes dados.
A IA é razoável em autenticação; bibliotecas cuidam da maior parte. Autorização é onde ela falha com frequência, porque autorização é específica das regras do seu app, e a IA não as conhece. O desastre clássico de livro-texto:
// VULNERÁVEL: verifica que você está logado, mas não QUEM você é
app.get("/admin/export-all-users", requireLogin, (req, res) => {
res.json(db.getAllUsers()); // qualquer usuário logado pode acessar isso
});
Esse está "protegido" — você precisa estar logado. Mas qualquer usuário logado, incluindo um que se cadastrou trinta segundos atrás, pode chamá-lo e baixar os dados de todo mundo. Autenticação presente, autorização ausente. A correção é verificar a permissão sobre a própria ação:
// SEGURO: confirma que este usuário é de fato um administrador
app.get("/admin/export-all-users", requireLogin, (req, res) => {
if (!req.user.isAdmin) return res.status(403).send("Forbidden");
res.json(db.getAllUsers());
});
Pense em dois portões que uma requisição precisa passar. Autenticação pergunta "você está logado?"; autorização pergunta "você tem permissão para fazer isto?" A violação acontece quando um app constrói o primeiro portão e esquece o segundo:
requisição ──▶ ┌──────────────────┐ ──▶ ┌──────────────────┐ ──▶ ação
│ AUTENTICAÇÃO │ │ AUTORIZAÇÃO │ roda
│ "está logado?" │ │ "ESTE usuário │
│ │ │ pode fazer ISTO?"│
└──────────────────┘ └──────────────────┘
✓ a maioria dos apps ✗ muitas vezes falta
constrói isso → a violação
EXEMPLO — /admin/export-all-users
usuário logado ──▶ [auth ✓] ──▶ [ sem verificação de autz ] ──▶ TODOS os usuários vazam
usuário logado ──▶ [auth ✓] ──▶ [ é admin? → 403 ] ──▶ bloqueado ✓
A mesma armadilha aparece em miniatura em todo lugar: um endpoint que devolve o pedido #1234 sem verificar se o pedido pertence ao usuário que fez a requisição. Qualquer um pode trocar o número na e ler o pedido de outra pessoa. A regra é sem graça e absoluta: verifique autorização em todo endpoint que toca dados, e não confie em um ID vindo do cliente. Não presuma que uma URL escondida é segura só porque está escondida — "ninguém sabe que isso existe" não é um controle de segurança.