IDOR: changing one number to see someone else's data

Insecure direct object references are the most common access-control bug in APIs: the endpoint checks that you are logged in, then fetches whatever record ID the request names.

Example

Vulnerable
app.get("/allocations/:userId", isLoggedIn, async (req, res) => {
  const docs = await allocations.find({ userId: req.params.userId });
  res.json(docs);
});
Fixed
app.get("/allocations", isLoggedIn, async (req, res) => {
  // the user comes from the session, never from the URL
  const docs = await allocations.find({ userId: req.session.userId });
  res.json(docs);
});

How it happens

Routes like /invoices/:id or /users/:userId/profile pass the ID from the URL straight into a database lookup. Being logged in as user 7 and requesting /invoices/8 returns user 8's invoice. Related mistakes: admin-only middleware that is defined but never added to a route, and writing the whole request body to a record, which lets the caller set fields like role or isAdmin.

How to fix it

Authorisation is per record, not per route.

  • Take the current user's ID from the session or token, not from the request
  • When an ID must come from the request, check the record belongs to the user before returning it
  • Apply role checks to every privileged route, and test them
  • Pick accepted fields explicitly instead of saving the whole body

How RepoVerse finds it

  • HighRecord looked up by an ID from the request, with no ownership check

    Changing the ID in the URL shows or changes another user's data (IDOR / BOLA).

    data flow · CWE-639

  • HighAdmin-only middleware is defined but never applied to a route

    Routes that were meant to be admin-only are reachable by any logged-in user, which is privilege escalation if they change data.

    data flow · CWE-285

  • ModerateWhole request body written to a database record

    The caller can set fields you never meant to expose — `isAdmin`, `role`, `balance`.

    data flow · CWE-915

Questions

What is the difference between IDOR and BOLA?
They are the same flaw. OWASP's API Security Top 10 calls it Broken Object Level Authorization (BOLA); the older web Top 10 called it Insecure Direct Object Reference.
Can static analysis find IDOR?
Partly. RepoVerse flags lookups keyed by a user-, account- or order-style ID from the request in handlers that never read the session or authenticated user. It marks these as likely, because only you know which records are meant to be public.

Related

Updated 2026-10-11