Articles / BFLA: When Users Reach Admin Functions
OWASP API5 · Broken Function Level Authorization

BFLA: When Users Reach Admin Functions

If Broken Object Level Authorization is about which records a user can reach, Broken Function Level Authorization is about which actions they can perform. The attack is often as simple as changing a verb or a path: a regular user sends the request an administrator would send, and the API — having checked that they are logged in but not that they are allowed — carries it out.

Functions in an API are its operations: delete a user, promote an account, export the customer list, change a price. Each should be gated by a check that the caller holds the role or permission that function requires. BFLA is what happens when that gate is missing or inconsistent — when the only thing standing between a standard user and an administrative action is that they didn't know the endpoint existed.

How the boundary gets crossed

guesses endpointOrdinary uservalid tokenAdmin route / verbDELETE /admin/users/42Server checks loginbut not rolePrivileged action runsFunction-level rolecheck missing
Authenticated but not authorised — a guessed verb runs the admin function.

Administrative and privileged endpoints are frequently guessable. If GET /api/users/me exists, an attacker will try GET /api/admin/users. If a user can PATCH their own record, they will try DELETE on someone else's. API structure is predictable, so relying on obscurity — an unlinked path, an undocumented method — is no defence at all.

Same login, a privileged verb the UI never offersPATCH /api/users/42 { "tier": "pro" } → 200 (allowed, it's mine)
DELETE /api/admin/users/42 → 200 (should be 403 — caller is not an admin)

The problem compounds when authorization is scattered across handlers. One developer remembers to check the admin role on the user-deletion endpoint; another, adding a bulk-export endpoint months later, does not. Because each check is written by hand in each function, the coverage is only ever as good as the least careful change — and the gaps don't show up in normal use, only under a deliberate probe.

Why it's API5: BOLA and BFLA are the two authorization failures on the list because both are pervasive and high-impact. BOLA exposes data across tenants; BFLA hands over the capabilities — the ability to act as an administrator, not just read as one.

Enforcing function-level authorization

  • Deny by default. Every function should require an explicit grant of the role or permission it needs; anything not explicitly allowed is refused. Never make access the default and denial the exception.
  • Centralise the check. Enforce authorization in shared middleware or a gateway that every route passes through, rather than trusting each handler to remember. Consistency is the whole game.
  • Separate admin surfaces clearly. Group privileged operations behind a boundary with its own enforced role requirement, and confirm that regular tokens cannot invoke them.
  • Don't rely on hidden endpoints. Assume every method and path is known. Obscurity delays discovery; it does not authorise anything.
  • Test every function with a low-privilege token. Automated tests that replay administrative requests as an ordinary user catch BFLA before release; unauthorised attempts should be logged and alerted on.

BFLA endures for the same reason BOLA does: it is an invariant that must hold on every privileged operation, forever, and hand-written checks erode as an API grows. The durable fix is architectural — make the authorization decision somewhere every request must pass, so a forgotten check fails closed. And since you can only protect the functions you know you expose, a current inventory of every endpoint and its required role is the ground truth the whole scheme depends on.

Test for it — in practice
  • As an ordinary user, call an admin-only route directly (for example swap /user/ for /admin/ in a request). If it works, the UI was your only access control.
  • Try a privileged HTTP method — DELETE or PUT — on an object you can only read. A success means the method, not just the path, is unguarded.

The full, at-scale version — enumerating every route, method and role combination for the function-level gaps a menu never shows — is what our assessment (and SecStudio agents) runs for you.

Keep reading
BOLA: The API Flaw That Tops the OWASP List