Autenticar não é autorizar: o erro de arquitetura por trás do IDOR
Trocar 1001 por 1002 na URL não devia te dar acesso à conta de outra pessoa.
Em muitos sistemas, dá.
Isso tem nome — IDOR (Insecure Direct Object Reference) — e é, há anos, a classe de falha nº 1 em APIs no OWASP (lá aparece como BOLA: Broken Object Level Authorization). Não é hacker genial, não é malware: é o sistema confiando no identificador que o próprio usuário mandou.
O engano que sustenta a falha
Quase toda empresa investe pesado em login: MFA, HTTPS, política de senha, SSO. E assume que está segura.
Mas autenticação responde "quem é você?".
Autorização responde "isso aqui é seu?".
São duas perguntas diferentes, e o código precisa responder as duas em todo endpoint que recebe um ID. Quase ninguém testa a segunda — e é exatamente aí que mora o IDOR.
GET /api/pedidos/1002
Authorization: Bearer <token válido do usuário dono do pedido 1001>
Token válido? Sim. Usuário autenticado? Sim. O pedido 1002 é dele? Ninguém perguntou.
O caso que realmente machuca
Vazar dado alheio já é grave (e no Brasil vira LGPD: dado pessoal exposto é incidente reportável — o custo deixa de ser técnico e vira jurídico e de reputação). Mas o IDOR mais perigoso não é o que lê. É o que deixa um usuário agir no lugar de outro:
- cancelar o pedido alheio;
- transferir a partir de uma conta que não é dele;
- alterar cadastro, aprovar operação, resetar senha de terceiro.
GET vaza. POST, PUT e DELETE destroem.
Por que if espalhado não resolve
O antipadrão clássico: cada feature faz sua própria checagem de dono, quando lembra. Funciona na sprint em que foi escrito — e reabre o buraco na sprint seguinte, no endpoint novo que ninguém lembrou de proteger.
Autorização de objeto é decisão de arquitetura, centralizada:
- uma camada/middleware por onde toda busca de recurso passa (
buscarDoUsuario(recursoId, usuarioId)em vez debuscarPorId(recursoId)), de preferência imposta no repositório/ORM — escopo por dono by default, não por lembrança; - IDs não sequenciais (UUID) ajudam contra enumeração, mas não são a correção — são obscuridade; a correção é a checagem de posse;
- WAF e firewall não salvam: eles não têm como saber se o pedido
1002é seu. Só o seu domínio sabe.
Como testar (o teste que quase ninguém faz)
Entre no seu sistema com dois usuários de teste, A e B. Pegue o token de A e chame os endpoints com IDs de recursos de B — leitura e escrita. Automatize isso na suíte: um teste de autorização por recurso é barato e pega a regressão que o code review deixa passar.
Se a sua suíte testa login mas não testa posse, vocês testam a porta e deixam o cofre aberto.
Pergunta honesta para o seu time: no último endpoint que vocês subiram com um ID no path, quem checou o dono — o código ou a sorte?
Escrevo a série segurança sem hype — falhas e golpes explicados antes de virarem incidente.