O primeiro bug de verdade que a maioria das pessoas encontra é uma vulnerabilidade IDOR, e normalmente elas o encontram trocando um único dígito. Você abre o seu próprio pedido em /orders/4417, digita 4418 por curiosidade, e o endereço de entrega de um desconhecido aparece na tela. Sem payload, sem truque de codificação, sem código de exploração. Apenas um número em que o servidor confiou. Se você quiser sentir esse momento antes de ler mais uma palavra sobre o assunto, abra o lab IDOR Explorer da HackerDNA e comece a trocar identificadores.
O IDOR faz parte do controle de acesso quebrado, a primeira posição do OWASP Top 10, e é o achado mais comum em programas de bug bounty por um bom motivo: leva dez segundos para testar e os desenvolvedores continuam entregando. Este guia cobre o que é de fato um IDOR, como caçá-lo direito, as "correções" que não corrigem nada, e como fechar o buraco de vez.
Resumo: uma vulnerabilidade IDOR (Insecure Direct Object Reference, referência direta insegura a objeto) acontece quando a aplicação recebe um identificador do usuário, busca o objeto correspondente e nunca verifica se aquele usuário tem permissão para obtê-lo. O bug não é a referência. É a checagem de propriedade que ficou faltando. Você encontra IDORs mantendo duas contas lado a lado e repetindo as requisições da conta A com os identificadores da conta B, e os corrige com uma verificação no servidor amarrada à sessão, não deixando os identificadores mais difíceis de adivinhar.
O que é uma vulnerabilidade IDOR?
IDOR significa Insecure Direct Object Reference, ou referência direta insegura a objeto. É uma falha de controle de acesso em que a aplicação expõe uma referência a um objeto interno (uma linha do banco, um arquivo, um documento) e deixa qualquer usuário logado fornecer essa referência sem verificar se ele é o dono do objeto. Troque a referência, receba outro objeto.
Corte o nome ao meio e ele se explica sozinho. Uma referência direta a objeto é normal e inevitável: toda aplicação precisa de alguma forma de dizer "me dê o registro 4417". A parte insegura é a checagem de autorização que não existe. Sua aplicação não está quebrada porque 4417 aparece na URL. Ela está quebrada porque o servidor nunca perguntou se quem pediu o 4417 tem algum motivo para vê-lo.
Por baixo, isso corresponde ao CWE-639: Authorization Bypass Through User-Controlled Key, que o MITRE classifica como de alta probabilidade de exploração. O MITRE lista "Insecure Direct Object Reference (IDOR)" e "Broken Object Level Authorization (BOLA)" como nomes alternativos da mesma fraqueza, então se você encontrar os três termos em um relatório, todos descrevem a mesma falha.
A versão curta que todo iniciante deveria decorar: autenticação pergunta quem você é, autorização pergunta o que você tem permissão de tocar. Um IDOR é uma aplicação que acertou a primeira pergunta e pulou a segunda.
Como funciona um ataque IDOR, passo a passo
Como funciona um ataque IDOR? Você entra como usuário legítimo, encontra uma requisição que carrega um identificador que você controla, troca esse identificador pelo de outra pessoa e envia. Se o servidor devolver os dados dela em vez de um erro, o controle de acesso está quebrado. Não existe burla do login, porque você nunca precisou de uma.
Aqui está a troca completa. Você está logado em um portal de suporte como cliente comum e abre um dos seus próprios chamados:
GET /api/tickets/4417 HTTP/1.1
Host: helpdesk.acme.example
Cookie: session=a9f31c0b7e2d...
HTTP/1.1 200 OK
{"id":4417,"owner":"[email protected]","subject":"Refund request","body":"..."}
Você muda um caractere e envia de novo:
GET /api/tickets/4418 HTTP/1.1
Host: helpdesk.acme.example
Cookie: session=a9f31c0b7e2d...
HTTP/1.1 200 OK
{"id":4418,"owner":"[email protected]","subject":"Card declined","body":"..."}
O servidor conferiu o seu cookie, decidiu que você estava logado e então leu o chamado 4418 do banco porque você pediu. Nada naquele trecho de código comparou owner com a sua sessão. Essa lacuna é a vulnerabilidade inteira.
- Consiga uma sessão autenticada. Cadastre-se ou entre como usuário comum. Você não está atacando o login, está abusando do que uma conta normal já alcança.
- Encontre uma referência que você controla. Observe o tráfego e anote cada identificador, nome de usuário, nome de arquivo e número de referência que o navegador envia. Cada um é um candidato.
- Troque e leia a resposta com atenção. Um
200com dados de outra pessoa é um IDOR confirmado. Um403significa que aquele endpoint verifica. Um404costuma significar que a verificação existe e que a aplicação esconde até a existência do registro, o que é boa prática. - Prove o impacto e pare. Um único registro pertencente a uma segunda conta que você controla já basta para o relatório. Extrair dez mil registros é um vazamento de dados com o seu nome nele.
Leitura, escrita e cego: as três formas de IDOR
A maioria dos artigos para em "você consegue ler os dados dos outros". Caçadores de bugs fazem uma segunda pergunta: dá para escrever também? Essa é a diferença entre exposição de informação e tomada de conta.
IDOR de leitura (exposição)
Uma requisição GET devolve um objeto que não é seu. Faturas, prontuários, mensagens privadas, arquivos enviados, chamados de suporte. É a forma mais comum e a mais fácil de provar. A gravidade depende inteiramente do que o objeto contém: o nome público de outro usuário é ruído; o passaporte digitalizado dele é crítico.
IDOR de escrita (adulteração e tomada de conta)
Um POST, PUT ou PATCH modifica um objeto que não é seu. O caso clássico é o endpoint de atualização de perfil que aceita um user_id no corpo: troque pelo de outra pessoa, coloque o seu e-mail no lugar do dela e dispare uma redefinição de senha. Essa sequência transforma um "médio" em tomada completa da conta, e é por isso que você deve sempre testar o caminho de escrita mesmo quando a leitura está bem trancada.
IDOR cego (nenhum dado volta)
Alguns endpoints devolvem um 200 vazio ou uma mensagem seca de sucesso, não importa de quem seja o objeto tocado. Isso não quer dizer que falhou. Se POST /api/invites/4418/resend responde {"status":"sent"}, verifique se um e-mail realmente chegou na caixa da segunda conta. Na prática, é aqui que os iniciantes desistem cedo demais, porque o corpo da resposta parece sem graça e o efeito colateral acontece em um lugar que eles não estavam olhando.
Onde os IDORs se escondem em aplicações modernas
Todo mundo olha a barra de endereços, e é justamente por isso que os IDORs da barra de endereços quase sumiram das aplicações maduras e os interessantes vivem em outro lugar. Estes quatro pontos rendem mais achados, mais ou menos em ordem de retorno.
- Corpos de requisição JSON de APIs internas. Aplicações de página única enviam muito mais parâmetros do que a URL mostra. Um endpoint como
PATCH /api/v2/profilecarregando{"user_id":4417,"email":"..."}é o alvo mais valioso na maioria dos sites, porque o front-end sempre manda o identificador certo e ninguém testou o que acontece quando ele não manda. - Endpoints de exportação, download e relatório. Frequentemente acrescentados depois por outro time, e frequentemente pulando o middleware de autorização que o resto da aplicação usa.
GET /reports/download?ref=Q3-4417.pdfvale dez minutos do tempo de qualquer um. - Cabeçalhos personalizados controlados pelo cliente. Algumas APIs passam identidade ou tenant em cabeçalhos como
X-Account-Id. Se o servidor lê esse cabeçalho em vez de derivar a conta da sessão, você tem um IDOR que nunca aparece na URL nem no corpo. - Identificadores aninhados e secundários. Uma requisição como
GET /api/teams/12/members/4417costuma validar que você pertence ao time 12 e depois confiar totalmente no identificador do membro. Trocar o identificador externo devolve um403limpo; trocar o interno devolve o registro. Teste todo identificador do caminho, não só o último.
GraphQL merece menção própria. Uma única consulta node(id: "...") pode expor objetos que a API REST protege corretamente, porque a autorização foi escrita endpoint a endpoint e o GraphQL reduziu cem endpoints a um. Se um alvo roda GraphQL, comece por ali.
Como testar vulnerabilidades IDOR
Como testar uma vulnerabilidade IDOR? Crie duas contas, capture as requisições que a conta A faz aos próprios recursos e repita cada requisição usando o cookie de sessão de A e os identificadores de B. Qualquer resposta que devolva os dados de B ou altere o estado dele é um IDOR. Duas contas são a metodologia inteira, e essa é a parte que os scanners não fazem por você.
- Crie duas contas e mantenha-as separadas. Use dois navegadores ou dois contêineres para que as sessões nunca se misturem. Crie um objeto distinto em cada uma (um chamado com o título "canary-B", por exemplo) para saber na hora de quem são os dados que você está vendo.
- Passe tudo por um proxy e monte um mapa. Navegue por toda a aplicação através de um proxy de interceptação com a conta A, depois releia o histórico e anote cada parâmetro que pareça um identificador. Nosso tutorial de Burp Suite mostra como fazer o proxy e o navegador conversarem, caso você nunca tenha configurado um.
- Troque no Repeater, uma requisição por vez. Substitua o identificador de objeto de A pelo de B e compare as respostas. Depois refaça o exercício sem nenhum cookie de sessão, o que às vezes revela acesso não autenticado que ninguém esperava.
- Automatize a parte chata. A extensão gratuita Autorize do Burp repete cada requisição que você envia através da sessão de uma segunda conta e sinaliza as que deveriam ter sido bloqueadas. Ela transforma uma tarde de trocas manuais em uma lista que você revisa em vinte minutos.
- Teste também os caminhos de escrita e exclusão. Um
GETbem trancado não diz nada sobre oPUTcorrespondente. Foram escritos por desenvolvedores diferentes, em dias diferentes.
Um hábito que vale construir cedo: registre os pares exatos de requisição conforme avança. Um relatório que mostra a requisição A (sua conta, seu registro, 200) ao lado da requisição B (sua sessão, o registro dele, 200) é triado rápido. Um relatório que diz "eu conseguia ver dados de outros usuários" é fechado como "faltam informações".
Correções que não corrigem
Quando um time recebe um relatório de IDOR, o primeiro instinto costuma ser tornar o identificador mais difícil de adivinhar. Esse instinto está errado, e entender o porquê separa quem compreendeu o bug de quem o decorou. Impossível de adivinhar não é a mesma coisa que não autorizado.
- Mudar para UUIDs. Identificadores aleatórios aumentam o custo da enumeração, o que é genuinamente útil, mas não são uma checagem de permissão. UUIDs vazam o tempo todo: links compartilhados, cabeçalhos de referrer, exportações CSV, capturas de tela mandadas ao suporte e a própria busca da aplicação. Assim que um vaza, o endpoint que nunca verificou propriedade continua não verificando.
- Codificar o identificador. Um parâmetro com
NDQxNw==parece opaco por uns quatro segundos. É o base64 de4417. Hash não é muito melhor quando não tem sal: um identificador comob1d5781111d84f7b3fe45a0852e59758cd7a87e5é só o SHA-1 de um inteiro pequeno, e qualquer um consegue pré-calcular o primeiro milhão. - Verificar no cliente. Se o navegador decide se mostra o botão de editar, o servidor ainda precisa decidir se honra a requisição. Atacantes não apertam botões, eles enviam requisições.
- Bloquear um único método HTTP. Negar
POST /admin/records/4418enquantoPUTeDELETEpassam tranquilos é um padrão real em código real, geralmente causado por uma regra de rota que listou os métodos na mão.
Uma segunda categoria é o filtro que uma pequena mudança contorna. id=4418 pode ser bloqueado enquanto id[]=4418 chega como array e segue outro caminho no código, e enviar os dois com id=4417&id=4418 elege vencedores diferentes em frameworks diferentes. Não são ataques espertos. São a prova de que a aplicação valida um formato em vez de verificar uma permissão.
Quanto custaram os vazamentos reais por IDOR
O IDOR é tratado como bug de iniciante, o que o subestima bastante. Em julho de 2023, a CISA, a NSA e o Australian Cyber Security Centre publicaram um comunicado conjunto chamado Preventing Web Application Access Control Abuse justamente por causa do estrago que essa única classe de falha continuava causando. Três dos incidentes que ele documenta:
- 2019: mais de 800 milhões de arquivos financeiros pessoais expostos em uma empresa americana de serviços financeiros.
- 2021: centenas de milhares de dispositivos móveis expostos por aplicativos de stalkerware com falhas de IDOR.
- 2012: dados pessoais de mais de 100 mil donos de dispositivos móveis obtidos no site de uma empresa do setor de comunicações.
O caso de 2019 é o que todo testador web deveria conhecer. A First American Financial Corporation, uma seguradora de títulos de propriedade da Fortune 500, mantinha um sistema de compartilhamento de documentos que numerava sequencialmente os documentos de fechamento de imóveis. Quem tivesse o link de um documento podia editar o número e ler o seguinte, e o conjunto exposto voltava até 2003: números de seguro social, dados bancários, digitalizações de carteiras de motorista. Segundo a ação da SEC de junho de 2021, o próprio time de segurança da empresa havia documentado a falha em um teste de intrusão manual meses antes de ela vir a público, e ela nunca foi corrigida conforme a política interna. A First American pagou 487.616 dólares para encerrar a acusação sobre controles de divulgação.
A parte útil é essa sequência. O bug foi encontrado internamente, por uma pessoa, fazendo exatamente o exercício de duas contas descrito acima. E então ficou ali. A falha técnica era uma verificação faltando; a falha cara era organizacional.
A classe não foi a lugar nenhum. Controle de acesso quebrado é o A01 do OWASP Top 10 2025, construído a partir de 40 CWEs mapeadas, cerca de 1,84 milhão de ocorrências registradas e 32.654 CVEs associadas. A OWASP coloca a forma de API dele em primeiro lugar no API Security Top 10, classificando sua prevalência como generalizada e sua explorabilidade como fácil.
Como corrigir uma vulnerabilidade IDOR
Como corrigir um IDOR? Busque o objeto e então verifique se a sessão autenticada tem permissão para aquele objeto específico, antes de devolver qualquer coisa. A verificação pertence ao servidor, no mesmo lugar em que os dados são buscados, e precisa usar a identidade vinda da sessão, não algum valor enviado pelo cliente.
Na prática, esta é a diferença entre vulnerável e corrigido:
# Vulnerable: the ID decides everything
ticket = Ticket.get(request.params["id"])
return ticket.to_json()
# Fixed: ownership is part of the lookup
ticket = Ticket.get(request.params["id"])
if ticket is None or ticket.owner_id != session.user_id:
return http_404()
return ticket.to_json()
Devolver 404 em vez de 403 quando a verificação falha é um detalhe pequeno que vale adotar. Um 403 confirma que o registro 4418 existe, o que entrega ao atacante um oráculo de existência funcional mesmo com os dados protegidos.
- Negue por padrão. Recursos começam fechados e só abrem por uma regra explícita. Um endpoint novo que alguém esqueceu de proteger deve falhar fechado, não escancarado.
- Coloque a verificação onde estão os dados. Um gateway que confirma sessão válida não é autorização. Se a única checagem mora na borda, toda chamada interna de serviço roda desprotegida.
- Centralize a política. Uma camada de autorização por onde toda requisição passa é melhor do que checagens por endpoint copiadas na mão, porque as cópias divergem e uma delas vai estar errada.
- Alerte sobre o padrão, não sobre a requisição. Um
403é erro de digitação. Quatrocentos deles percorrendo identificadores consecutivos a partir de uma mesma sessão é enumeração em andamento, e isso deveria acordar alguém.
Aproveite e adicione um teste de regressão. Um teste que entra como usuário B e exige um 404 no objeto do usuário A custa umas seis linhas e impede a falha de voltar na próxima refatoração do controlador.
IDOR, BOLA e controle de acesso quebrado
Três termos, uma mesma falha por baixo, escopos diferentes. Distingui-los deixa relatórios e entrevistas mais fluidos.
Controle de acesso quebrado é a categoria guarda-chuva. Cobre toda falha de autorização: alcançar uma página administrativa que nunca foi concedida, elevar um papel, adulterar o método da requisição, e o IDOR. Nosso guia de controle de acesso quebrado mapeia o conjunto completo.
IDOR é um tipo específico dentro desse guarda-chuva: uma referência de objeto controlada pelo usuário, buscada sem checagem de propriedade. Todo IDOR é uma falha de controle de acesso. A maioria das falhas de controle de acesso não é IDOR.
BOLA (Broken Object Level Authorization) é como a OWASP chama o IDOR no seu API Security Top 10, onde ele ocupa o primeiro lugar. Mesmo bug, nome com sotaque de API. Se um analista de triagem reclassificar seu relatório de IDOR como BOLA, nada mudou além do vocabulário.
Considerações legais e éticas
Lembrete essencial: sempre obtenha autorização escrita e explícita antes de testar qualquer aplicação em busca de IDOR. Trocar um identificador para ler o registro de outra pessoa em um sistema que não é seu configura acesso não autorizado sob o Computer Fraud and Abuse Act (EUA), o Computer Misuse Act (Reino Unido) e leis equivalentes no mundo todo. O fato de o servidor ter respondido não é permissão, e "eu só mudei um número" nunca funcionou como defesa.
- Teste apenas em sistemas seus, em labs feitos para isso, ou dentro do escopo escrito de um programa de bug bounty ou de um contrato.
- Use duas contas que você controla. Confirmar um IDOR contra o registro de um desconhecido real significa que você acessou os dados de uma pessoa real, mesmo sem querer.
- Pare na prova de impacto. Um registro, com captura de tela, é um relatório. Percorrer toda a faixa de identificadores é um vazamento, e as regras dos programas dizem isso de forma explícita.
- Se uma resposta trouxer dados pessoais que você não esperava, não os salve. Anote a requisição, o código de status e os nomes dos campos, diga isso no relatório e dê tempo ao time para corrigir antes de publicar qualquer coisa.
Perguntas frequentes
O que significa IDOR?
IDOR significa Insecure Direct Object Reference, referência direta insegura a objeto. O termo descreve uma aplicação que aceita do usuário uma referência a um objeto (identificador, nome de arquivo ou chave) e devolve o objeto correspondente sem verificar se aquele usuário está autorizado a acessá-lo. O MITRE registra a falha como CWE-639, e o API Security Top 10 da OWASP chama a mesma fraqueza de Broken Object Level Authorization.
O IDOR ainda é comum em 2026?
Sim. O controle de acesso quebrado, categoria à qual o IDOR pertence, ocupa o primeiro lugar do OWASP Top 10 2025, a partir de cerca de 1,84 milhão de ocorrências registradas e 32.654 CVEs. Aplicações de página única e back-ends de aplicativos móveis o tornaram mais comum, não menos, porque agora a autorização precisa ser aplicada em centenas de endpoints de API em vez de um punhado de páginas renderizadas no servidor.
Um scanner de vulnerabilidades encontra IDOR?
Na maioria das vezes não. Um scanner vê que a requisição devolveu 200, mas não tem como saber que o registro deveria pertencer a outra pessoa, porque propriedade é regra de negócio. Ferramentas que repetem o seu tráfego pela sessão de uma segunda conta, como a extensão Autorize do Burp, chegam bem mais perto, porque você fornece a segunda identidade que dá sentido à comparação.
UUIDs evitam vulnerabilidades IDOR?
Não. Identificadores aleatórios deixam a enumeração mais lenta, o que vale a pena, mas não são uma checagem de autorização. UUIDs vazam por links compartilhados, cabeçalhos de referrer, exportações e capturas de tela. Se o servidor continua sem verificar se a sessão é dona do objeto, a falha segue intacta assim que um identificador escapa.
IDOR é a mesma coisa que CSRF?
Não. Em um ataque CSRF, o navegador da vítima é enganado para enviar uma requisição que a vítima tem permissão de fazer. Em um IDOR, você envia da sua própria sessão autenticada uma requisição que nunca teve permissão de fazer. O CSRF se defende com tokens antifalsificação e cookies SameSite; o IDOR se defende com verificações de propriedade no servidor.
Qual é a gravidade de uma vulnerabilidade IDOR?
A gravidade depende do objeto e da ação. Ler o nome de exibição de um desconhecido é baixo. Ler os documentos de identidade dele é crítico. Se a falha também permitir escrita, o atacante costuma conseguir trocar o e-mail da vítima e disparar uma redefinição de senha, transformando o achado em tomada completa da conta.
Parte da série OWASP Top 10
Artigos relacionados:
- Controle de acesso quebrado explicado
- Guia da vulnerabilidade IDOR
- OWASP API Security Top 10
- Tutorial de injeção SQL
- O ataque SSRF explicado
Seus próximos passos
Uma vulnerabilidade IDOR é a lição mais barata que a segurança de aplicações vai te dar: um identificador trocado, uma requisição sem verificação, e a diferença entre autenticação e autorização deixa de ser uma definição decorada pela metade. Ler sobre isso faz muito pouco. Trocar 4417 por 4418 e ver o registro de um desconhecido carregar faz tudo de uma vez. Comece de graça, sem cartão de crédito, no lab IDOR Explorer, depois encare a versão de API no API Breaker, onde os identificadores se escondem no JSON em vez da URL. Para ver como isso se encaixa ao lado de injeção, XSS e o resto do OWASP Top 10, o curso Web Attacks percorre cada risco em labs guiados no navegador. Aprenda a achar a verificação que falta e depois vá escrever a que impede tudo isso.