API Security Broken Function Level Authorization
Broken Function Level Authorization (BFLA) is different from BOLA. Where BOLA is about accessing another user's data objects, BFLA is about accessing functionality that your role should not permit — such as administrative actions, privileged operations, or management endpoints.
The Difference Between BOLA and BFLA
BOLA (Object Level):
Regular user Ritu accesses another user Sanjay's invoice.
She has the same privilege level as Sanjay.
She is accessing DATA she should not see.
BFLA (Function Level):
Regular user Ritu accesses the DELETE /api/users/{id} endpoint.
She should not be able to delete users — only admins can.
She is accessing a FUNCTION she should not use.
Both vulnerabilities = missing authorization check.
Different scope: data access vs function access.
Why BFLA Happens
Common Developer Mistakes:
Mistake 1: Hiding endpoints instead of protecting them
Admin endpoints not shown in the UI.
Developer assumes users will not find them.
Reality: Attackers enumerate endpoints using:
- Source code in public repositories
- JavaScript bundles in the browser
- API documentation or Swagger UI
- Common admin path guessing (/admin, /manage, /internal)
Mistake 2: Frontend-only access control
Admin buttons hidden from regular users in the UI.
The underlying API endpoint has no server-side role check.
Attacker calls the API directly (without the UI).
No hidden button. No UI restriction. The API responds.
Mistake 3: Different HTTP methods not protected equally
GET /api/users → Requires authentication ✓
DELETE /api/users/101 → No role check added ✗
Developer secured the read endpoint but forgot
to add role checks to the write and delete endpoints.
Attack Scenarios
Scenario 1: Accessing Admin CRUD Endpoints
API for a content management platform:
Documented endpoints for regular users:
GET /api/articles → Read articles
GET /api/articles/{id} → Read one article
POST /api/articles → Create article
Undocumented admin endpoints (but they exist!):
DELETE /api/articles/{id} → Delete any article
POST /api/users/ban → Ban a user
GET /api/users → List ALL users (with private data)
PUT /api/settings → Modify platform settings
A curious attacker tries:
DELETE /api/articles/1
Authorization: Bearer regular_user_token
→ Expects 403 Forbidden
→ Receives: 200 OK — Article deleted!
The admin endpoint exists and works but was not protected.
Scenario 2: HTTP Method Manipulation
The same endpoint URL often handles multiple HTTP methods. Each method may have different authorization requirements. Example: GET /api/users/101 → Should work for any authenticated user (own profile) PUT /api/users/101 → Should work only for the profile owner DELETE /api/users/101 → Should work only for admin Vulnerable implementation checks role for GET but not DELETE: Regular user sends: DELETE /api/users/202 → The server processes it without an admin check. → User 202 deleted. Testing approach: For every URL that supports GET, also test POST, PUT, PATCH, DELETE, and OPTIONS. Each method must have its own authorization check.
Scenario 3: Parameter-Based Role Bypass
Some APIs accept a role or permission parameter in the request:
Normal request:
POST /api/users/register
Body: { "username": "newuser", "email": "new@example.com" }
Attacker adds role parameter:
POST /api/users/register
Body: { "username": "newuser", "email": "new@example.com", "role": "admin" }
If the server accepts and processes the "role" field without filtering:
→ The new account is created as an admin.
→ Attacker has full administrative access immediately.
This is also related to Mass Assignment (Topic 18).
Scenario 4: API Version Bypass
APIs often have multiple versions. Older versions may lack controls added later.
Current API:
DELETE /api/v3/users/{id} → Checks admin role ✓
Old API (still running):
DELETE /api/v1/users/{id} → Admin check not added in old version ✗
Attacker tries old version:
DELETE /api/v1/users/101
→ No admin check. User deleted.
Always apply security patches to ALL active API versions.
Decommission old versions that are no longer needed.
Finding BFLA Vulnerabilities
Common Admin Endpoint Paths to Test: /admin, /api/admin, /api/v1/admin /manage, /management, /api/manage /internal, /api/internal /console, /api/console /debug, /api/debug /config, /api/config, /api/settings /users/all, /api/users/list /export, /api/export, /api/dump /metrics, /api/metrics /health-private, /api/status/detailed Testing methodology: 1. Obtain any valid user token (even a free/basic account). 2. Try accessing each admin endpoint with this token. 3. Try all HTTP methods (GET, POST, PUT, PATCH, DELETE) on each path. 4. Any 200 OK response to a privileged operation is a BFLA.
Prevention
Prevention Rule 1: Deny by default
Every endpoint returns 403 by default for all roles.
Explicitly grant access to specific roles for specific endpoints.
Framework-level: Use decorators or middleware to declare requirements.
Express.js example:
router.delete('/api/users/:id',
authenticateToken, // Must be logged in
requireRole('admin'), // Must be admin role
deleteUserHandler
);
Prevention Rule 2: Centralized access control
Do not scatter role checks throughout the codebase.
Use a single authorization middleware or library.
Benefits:
Easy to audit: all auth decisions in one place.
Consistent application across all endpoints.
Easier to update when requirements change.
Prevention Rule 3: OpenAPI spec enforcement
Define allowed roles in the API specification.
Use middleware that automatically enforces spec rules.
Any request to an undocumented endpoint returns 404.
Any request with insufficient role returns 403.
Prevention Rule 4: Separate admin APIs
Host admin APIs on a completely separate service.
Restrict access by IP: only allow from company VPN.
Apply additional authentication (MFA required for admin).
Attacker from the internet cannot reach the admin API at all.
Prevention Rule 5: Test with multiple roles
For every endpoint in your API, test with:
- Unauthenticated (no token)
- Basic/free user token
- Standard user token
- Premium/advanced user token
- Admin token
Document which role should succeed for each test case.
Any unexpected success = BFLA vulnerability.
Key Points
- BFLA occurs when regular users can access administrative or privileged API functions without proper role checks.
- Hiding endpoints is not security. Attackers enumerate endpoints from JavaScript bundles, documentation, and common path guessing.
- Frontend-only access control provides zero protection — APIs must always enforce authorization server-side.
- Test all HTTP methods on every endpoint. Authorization checks must apply to GET, POST, PUT, PATCH, and DELETE independently.
- Old API versions often lack security controls added to newer versions. Decommission unused versions and patch all active ones.
- Use deny-by-default authorization: explicitly permit access rather than blocking specific requests.
