Broken Function Level Authorization
A read-only API account calls staff-only /admin endpoints and the server answers, because it checks the session is valid but never checks the caller's role. An analyst pulls the customer roster and queues a payout, then you ship a router-level role guard.
What Is Broken Function Level Authorization?
Broken function level authorization (OWASP API5:2023) is a broken-access-control failure where an API validates that a caller holds a valid session and then runs whatever function they request, without checking that the caller's role is permitted to invoke it. The classic shape: admin or staff-only endpoints share the same authenticated API as ordinary users, the privileged controls are hidden from low-privilege roles in the interface, and the endpoints themselves carry no role check, so any valid token reaches them. It is distinct from broken object level authorization, where an authenticated user reaches another user's object by changing an identifier, and from a token-forging privilege escalation, where the attacker tampers with their own credential; here the token is honest and low-privilege, and the missing check is on the function. This exercise puts you on both sides. As Bob, a self-serve developer account with an honest read-only analyst token on Fennmark's payments API, you confirm your role with GET /me, then call GET /admin/customers and pull the full customer roster, and POST /admin/disbursements to queue a $48,000 payout to an account you control, every call returning 200. As Alice, on the receiving end of a monitoring alert, you open the admin router, see that authenticate runs on every route but the role guard that was already imported is never applied, and ship the durable fix: a router-level authorize('admin') guard that runs after authentication on every admin function and refuses non-admin sessions with 403, so the whole admin surface is deny-by-default. The exercise closes with quiz questions on the authentication-versus-authorization distinction, why hiding functions in the UI is not access control, where the caller's role must come from, and why a centralized guard beats a per-handler check.
What You'll Learn in Broken Function Level Authorization
- Recognize broken function level authorization: a valid session reaching a privileged function because the endpoint checks who is calling but not whether their role may call it
- Distinguish it from broken object level authorization (changing an object id) and from token-forging privilege escalation (tampering with your own credential); here the token is honest and low-privilege and the function check is missing
- Understand that hiding an admin control in the UI or omitting a route from documentation is not access control, because clients call the API directly and the endpoint still answers
- Apply the fix: enforce authorization server-side on every privileged function, take the caller's role from the authenticated session rather than the request, and prefer a deny-by-default guard at the router boundary so new routes inherit the check
- Audit every admin, internal, and staff-only endpoint for a missing role check, especially where privileged and ordinary functions share one authenticated API
Broken Function Level Authorization — Training Steps
-
A read-only seat
Fennmark runs a payments platform, and it hands out self-serve developer accounts to anyone who signs up. Bob took one, with a throwaway identity. His seat is an Analyst: read-only, sandbox-scoped, nothing sensitive. He opens the developer console to get his bearings on what his account is and what the API offers.
-
Admin functions, in plain sight
Bob's seat is read-only, so the admin controls are hidden from him in the interface. The API reference is not hidden, though, and it lists every staff-only function right alongside the ones he is allowed to call.
-
What the token says
Before he touches anything privileged, Bob checks what identity his own token carries. He points the API Tester at the account endpoint and sends his session token in an Authorization header, the same way the app does.
-
An honest analyst
The server confirms exactly what Bob expected. His token is genuine, and it says plainly what he is.
-
Call an admin function
Bob keeps the same request and the same read-only token, and changes only the resource in the URL to a function the reference marked staff-only: the full customer roster. If the API only checks that his session is valid and never checks his role, it will answer.
-
The whole roster, to an analyst
The admin function answered. Bob's read-only sandbox token just pulled the platform's customer records.
-
Move the money
Reading data is one thing. Bob now calls a function that changes state: the disbursement endpoint that queues a payout. He sends it with the same analyst token and points the destination at an account he controls.
-
A payout, queued by a sandbox account
The money-moving function ran too. No admin, no approval, no special credential.
-
Knowledge check
You just watched a read-only account read the customer roster and queue a payout. Lock in why.
-
The alert lands
You own Fennmark's back-office API. Overnight, monitoring flagged a self-serve developer account calling staff-only endpoints. Security operations has emailed you the details.