IDOR
Insecure Direct Object Reference
What is IDOR?
IDOR (Insecure Direct Object Reference) is an access control vulnerability in which an application exposes a direct reference to an internal object, such as a numeric ID in a URL, and fails to verify that the requesting user is authorized for that specific object. The user is authenticated, the request is well formed, and the server does exactly what it was asked: it just never asks “is this yours?”. Changing /invoices/1042 to /invoices/1043 and receiving someone else’s invoice is the canonical example. IDOR is the most common form of broken object-level authorization, the category that tops the OWASP API Security Top Ten.
How it shows up in real code
The vulnerable pattern is a lookup keyed only by the identifier from the request:
app.get("/api/invoices/:id", auth, (req, res) => {
res.json(db.invoices.findById(req.params.id));
});The auth middleware confirms who the user is, but nothing confirms the invoice belongs to them. Variants include sequential IDs that invite enumeration, “hidden” admin parameters like ?user_id=, download endpoints keyed by guessable filenames, and mobile or internal APIs assumed to be unreachable. Because every response looks legitimate, IDOR rarely trips scanners or error monitoring; it is a logic flaw, not a malformed input.
The fix
The fix pattern is an object-level authorization check on every access: scope each query by the owner (findOne({ id, userId: currentUser.id })) or verify ownership or role explicitly after the lookup, enforced in one shared layer rather than re-remembered in every handler. Replacing sequential IDs with UUIDs slows enumeration but is not a defense on its own; the check must exist regardless. Deny by default, and treat any handler that touches an ID without a scoped query as a finding.
Why it matters in a code audit
IDOR is exactly the class of bug that manual review exists for. Automated tools cannot know that invoice 1043 should not be visible to user 7; a human reading the handler sees the missing check immediately. Auditors sweep every endpoint that accepts an object identifier and ask one question per route: where is the ownership check? The pattern of “authenticated but not authorized” makes IDOR a sibling of CSRF, and it commonly co-occurs with SQL injection in codebases that grew faster than their review process. More examples are in the top vulnerabilities code audits catch.
A free code audit walks your endpoints and flags the ones that skip the ownership question.
Free · no strings shown later
Get your free code audit
A repo URL and two minutes of your time. A Webisoft engineer sends back written findings (security, tech debt, performance) with file-and-line specifics.
Request my free audit