CodePark/ questions / Access control (RBAC, ABAC, IDOR)
START PRACTICINGPRACTICE
Backend question · Auth & security › Access control (RBAC, ABAC, IDOR)

What's wrong with this endpoint, what is the vulnerability called, and how do you fix it?

app.get("/api/invoices/:id", requireAuth, async (req, res) => {
  const invoice = await Invoice.findById(req.params.id);
  if (!invoice) return res.sendStatus(404);
  res.json(invoice);
});

The handler checks that the caller is logged in. But it never checks that the invoice belongs to them. So any logged-in user can change the id in the URL and read other customers' invoices.

This is IDOR (Insecure Direct Object Reference). The OWASP API Security Top 10 calls it BOLA (Broken Object Level Authorization) and ranks it first, as API1.

The fix: check ownership or permission on the server, on every request that loads an object by id. For example:

  • Scope the query to the current user: Invoice.findOne({ _id: req.params.id, ownerId: req.user.id }).
  • Or use a policy function that also handles admins and shared access.

Return 404 or 403, and be consistent about which one.

Random UUIDs make ids harder to guess, but they are not a fix. Ids still leak through URLs, logs and shared links.

  • The user is logged in, but not allowed to access this object.
  • This is IDOR, called BOLA, and it is API1 in the OWASP API Top 10.
  • Check ownership on the server every time an object is accessed.
  • Scope the query by the current user, or use a policy check.
  • Ids that are hard to guess are not access control.