← All cybersecurity posts

BOLA (Broken Object Level Authorization): The Number One API Risk

Broken Object Level Authorization (BOLA) tops the OWASP API Security Top 10. It is the API version of IDOR: the API accepts an object identifier from the client and returns or modifies that object without checking that the caller is allowed to.

Anatomy of a BOLA bug

GET /api/v2/projects/7f3a.../members
Authorization: Bearer <token for user A>

The API verifies the token, so the user is authenticated. It loads the project by ID and returns the member list. It never asks: does user A belong to this project? Any authenticated user who obtains or guesses a project ID can read its members.

Where BOLA hides

  • Nested routes: /orgs/{orgId}/invoices/{invoiceId} checks the org but not that the invoice belongs to it.
  • Batch endpoints: POST /api/documents/bulk-get with a list of IDs, where only the first is checked.
  • GraphQL: node(id: "...") resolvers that fetch any object type by global ID.
  • File and export endpoints: /exports/{id}/download.
  • Mobile APIs, which are often less tested than the web app.
  • Secondary identifiers: email, username or slug used as a lookup key.

Why it is so widespread

  • Authentication middleware is applied globally, giving a false sense of security.
  • Authorisation must be implemented per resource, and one missed handler is enough.
  • Frontend code only requests the user's own objects, so normal testing never reveals the gap.

Preventing BOLA in code

Scope queries to the caller.

// Express + Prisma example
app.get("/api/projects/:id", auth, async (req, res) => {
  const project = await prisma.project.findFirst({
    where: { id: req.params.id, members: { some: { userId: req.user.id } } },
  });
  if (!project) return res.sendStatus(404);
  res.json(project);
});

Centralise policies. Use a single authorize(user, action, resource) function or a policy library, and require every handler to call it.

Enforce at the data layer too. Postgres row-level security, or tenant-scoped database clients, provide a backstop if a handler forgets.

Test it automatically. For every endpoint, write a test where a second user requests the first user's object and expects 404.

Finding BOLA

Testing for BOLA requires:

  1. At least two accounts, ideally in separate tenants.
  2. Capturing object IDs created by account A.
  3. Replaying every request type, including GET, PUT, PATCH and DELETE, with account B's credentials and account A's IDs.
  4. Checking for any data returned or change made.

This is mechanical but tedious across hundreds of endpoints, and impossible for scanners without identity awareness. SecurityInfinity's API agent runs exactly this cross-identity testing on every discovered endpoint and verifies each unauthorised access with evidence. Start free.

Frequently asked questions

Is BOLA the same as IDOR?

Essentially, yes. BOLA is the term OWASP uses for APIs, while IDOR is the older, more general term.

Do UUIDs prevent BOLA?

They make guessing harder but IDs leak through URLs, logs, shared links and other API responses. Authorisation is still required.

Should unauthorised requests return 403 or 404?

Returning 404 avoids confirming the object exists. Either is acceptable as long as no data is returned.

Find what attackers can see, before they do.

AI pentesting agents test your web app, API and cloud, and every finding comes with evidence and a fix. First report in about 10 minutes.

Stay ahead of attackers.

New vulnerabilities, breach write-ups and practical fixes. A few emails a month.