π What Is It?
Broken Function Level Authorization (BFLA) is the failure to check whether the caller is allowed to invoke a particular operation. Where BOLA is about which records you may touch, BFLA is about which actions you may perform: promoting a user, deleting a tenant, exporting billing, calling /admin/*, or using a method (DELETE) the UI never offers you.
The classic cause is hiding instead of enforcing: the front end simply doesn't render the admin button, and the endpoint behind it assumes nobody will ever call it. Attackers read the JavaScript bundle, the OpenAPI spec, or just guess - and call it directly.
β οΈ Common Exploits
- Guessed Admin Routes:
/api/admin/users,/api/v1/internal/* - Method Swap:
GETis allowed for all,DELETEon the same path is unguarded - UI-Only Controls: the button is hidden; the endpoint is not protected
- Role from the Client: server trusts
rolein the body, header, or an unverified token - Version Drift:
/v1still live and unguarded while/v2is hardened - Spec Leakage: Swagger/GraphQL introspection publishes every privileged operation
- Default-Allow Routing: new handlers ship without the authorization decorator
π΄ Attack Flow
β
2. Look for privileged verbs and paths the UI never calls for you
β
3. Call them with your own valid token
β
4. Vary the method and the version prefix where blocked
β
5. IMPACT: Privilege escalation - administrative actions from a basic account!
β Vulnerable Code
β Secure Code
β Prevention Checklist
- Deny by default - an unmapped route or method must be forbidden
- Enforce authorization server-side on every operation, never in the UI
- Derive roles and permissions from the server, not from client input
- Cover every HTTP method on every path, not just the ones the app uses
- Separate administrative APIs and gate them by role and network
- Keep one central policy (RBAC/ABAC) rather than per-handler checks
- Decommission old API versions; do not leave
/v1unguarded - Restrict Swagger/GraphQL introspection in production
- Return 404 for unauthorised privileged routes
- Add CI tests asserting a normal user gets 403/404 on every admin route
π Detection & Tools
Testing:
Policy:
How to Test:
- Replay every admin request with a low-privilege token
- Fuzz for
/admin,/internal,/debug,/v1paths - Try each method (
PUT,PATCH,DELETE) on known paths - Read the front-end bundle for endpoints your role never calls
- Check that older API versions enforce the same policy
π Real-World
These are documented incident classes - recurring patterns rather than single CVEs.
- Admin endpoints reachable by any user: the SPA hides the admin panel, but
POST /api/admin/*answers to any valid token. - Self-promotion to admin: a role-change operation intended for staff is callable by the account whose role it changes.
- Method gaps: read is authorised, but the matching
DELETEhandler was added later without the decorator. - Forgotten API versions: a deprecated
/v1kept alive for one legacy client bypasses every control added in/v2. - Client-supplied roles: a header or body field naming the caller's role is trusted by the server.
π Quick Tips
- DO NOT treat a hidden UI control as a security control
- DO NOT read the caller's role from the request
- DO deny by default and grant per operation
- DO test every method Γ route Γ role in CI
- DO retire old versions and internal routes
π Compliance
Related Standards:
- OWASP API Security Top 10 2019 - API5
- Maps to API5:2023 (unchanged)
- CWE-285 Improper Authorization
- CWE-862 Missing Authorization
- CWE-863 Incorrect Authorization