APIAccess ControlOWASP

BOLA vs. BFLA: the two API authorization failures that matter most

TrekShield Security Team · March 20, 2026 · 7 min read

The two most impactful classes of API vulnerability sound almost identical and are constantly confused: BOLA (Broken Object-Level Authorization) and BFLA (Broken Function-Level Authorization). They sit at the top of the OWASP API Security Top 10 because they’re common, high-impact, and invisible to automated tooling. Understanding the difference is the first step to testing for both.

BOLA: can you access this specific object?

BOLA — often called IDOR — is about which records you can reach. The API checks that you’re logged in, but not that the object you’re requesting belongs to you.

GET /api/orders/10432    -> your order (fine)
GET /api/orders/10433    -> someone else's order (BOLA)

Same endpoint, same permission level, different object. The function is one you’re allowed to call; the instance isn’t yours. In a multi-tenant product this is catastrophic — it can mean one customer reading another’s data at scale via enumeration.

BFLA: can you call this operation at all?

BFLA is about which actions you can perform. The API fails to check that your role is allowed to invoke a function — typically a privileged or administrative one.

DELETE /api/users/8821        (should be admin-only)
POST   /api/admin/refunds     (should be finance-only)

Here the problem isn’t the object — it’s that a regular user can reach an operation reserved for a higher privilege level. BFLA often hides in “hidden” admin endpoints that the UI never exposes but the API happily serves.

The one-line distinction

  • BOLA = right function, wrong object (horizontal — another user’s data).
  • BFLA = wrong function for your role (vertical — an action above your privilege).

Both are authorization failures. BOLA crosses a data boundary; BFLA crosses a privilege boundary.

Why automated tools miss both

Neither has a signature. A 200 OK returning another tenant’s order looks identical to a legitimate one. A successful admin call from a normal user looks like any other success. Detecting these requires knowing who the caller is and what they should be allowed to touch or do — semantic context a scanner doesn’t have. That’s why they need a human with multiple accounts.

How we test for each

For BOLA:

  1. Provision two isolated accounts (ideally two tenants).
  2. As Account A, replay requests substituting Account B’s object identifiers — in the path, query, body, and nested references.
  3. Test every verb: read is the start, but PUT/PATCH/DELETE on another’s object are often worse.
  4. Prove impact with the exact cross-account request/response pair.

For BFLA:

  1. Enumerate every function, including undocumented and admin-adjacent endpoints.
  2. As a low-privileged account, attempt privileged operations directly against the API.
  3. Try method and role tampering — GET vs POST, forced browsing to admin routes.
  4. Confirm the unauthorized action actually took effect, not just returned a success code.

How to defend

  • Enforce authorization at the data and function layer, derived from the authenticated session — never from client-supplied identifiers or hidden UI.
  • Centralize authorization in one well-tested policy layer instead of per-endpoint checks that drift.
  • Deny by default for every function; require an explicit allow for each role.
  • Add regression tests asserting that Account A can’t touch Account B’s objects (BOLA) and that low-privilege roles can’t call privileged functions (BFLA).

The takeaway

BOLA and BFLA are the quiet giants of API security: easy to introduce, invisible to scanners, and devastating when exploited. Testing for them takes multiple accounts, a methodical eye, and the discipline to prove impact — which is exactly how every API we touch gets tested.

Want proof your tenants are actually isolated?

A short scoping call, no obligation.