Trocar o id na URL mostra dados de outra pessoa: o que é IDOR e como corrigir
A rota pede login, mas não confere se o pedido é daquele usuário. Trocar /pedidos/123 por /pedidos/124 mostra o pedido de outra pessoa. Como achar e corrigir.
IDOR (Insecure Direct Object Reference) é o nome técnico de uma falha simples: o sistema confere que você está logado, mas não confere se aquilo que você pediu é seu. O id vem da URL ou do corpo do pedido, e a consulta usa esse id sem mais nada.
// ❌ confere o login, mas qualquer usuário logado lê QUALQUER pedido
const usuario = await usuarioLogado(req);
if (!usuario) return Response.json({ erro: "faça login" }, { status: 401 });
const { data } = await supabase.from("pedidos").select("*").eq("id", params.id).single();É uma das falhas mais comuns em app feito com IA, porque o código parece protegido: tem login, tem 401. Ela aparece quando a rota usa a chave de serviço (que ignora a RLS) ou quando o banco não tem regra de dono.
Como corrigir
Filtre SEMPRE pelo dono, usando a identidade que vem da sessão — nunca um userId enviado pelo navegador.
// ✅ o pedido tem de ser do usuário logado
const { data } = await supabase
.from("pedidos")
.select("*")
.eq("id", params.id)
.eq("user_id", usuario.id)
.single();
if (!data) return Response.json({ erro: "não encontrado" }, { status: 404 });- Vale para ler, alterar e apagar: o
updatee odeletepor id precisam do mesmo filtro de dono. - No Supabase, a RLS com
auth.uid() = user_idfaz esse filtro no banco — desde que a rota use a chave pública com a sessão do usuário, e não a chave de serviço. - Responda 404 (e não 403) quando o item não é da pessoa: assim ninguém descobre quais ids existem.
Como testar
- 1Crie duas contas de teste, A e B.
- 2Com A, crie um item e anote o id.
- 3Logado como B, peça esse id na rota (pelo navegador ou pelo Postman). Tem de dar 404.
Dicas curtas de segurança para quem cria com IA: siga @npx_vibedefender no Instagram.