Back to Cheat Sheets

๐Ÿ”“ Broken Access Control2025

OWASP Web Top 10 2025 ยท A01

CRITICAL RISK

๐Ÿ“‹ What Is It?

Broken Access Control occurs when an application fails to enforce restrictions on what authenticated users may do, letting them read or modify data and reach functionality outside their intended permissions. It is an authorization problem, not an authentication one, and consistently ranks as the most prevalent category in the OWASP Top 10.

A01 OWASP Rank
94% Apps With Some Form
34 Mapped CWEs

โš ๏ธ Common Attack Vectors

  • IDOR: Insecure Direct Object References
  • Privilege escalation: horizontal & vertical
  • Parameter tampering: injecting role / is_admin
  • Forced browsing: guessing unlinked URLs
  • Path traversal to reach restricted files
  • Missing function-level access checks

๐Ÿ”ด Attack Flow (IDOR)

1. Logs in, views /user/profile?id=12345
โ†“
2. Notices IDs are sequential
โ†“
3. Changes URL to /user/profile?id=12346
โ†“
4. Server performs no ownership check
โ†“
5. BREACH: reads another user's data!

โŒ Vulnerable Code

# Anyone can access any profile by changing user_id @app.route('/api/profile/<user_id>') def get_profile(user_id): user = database.get_user(user_id) return jsonify(user.to_dict())

โœ… Secure Code

@app.route('/api/profile/<user_id>') def get_profile(user_id): if not current_user.is_authenticated: abort(401, "Authentication required") user = database.get_user(user_id) if not user: abort(404, "User not found") # Verify ownership (or admin) before returning if current_user.id != user_id and not current_user.is_admin: abort(403, "Access denied") return jsonify(user.to_dict())

โœ“ Prevention Checklist

  • Deny by default; grant permissions explicitly
  • Enforce all authorization server-side
  • Check authorization on every request
  • Verify resource ownership in the query
  • Use one centralized access-control mechanism
  • Prefer non-sequential references (UUIDs)
  • Validate and whitelist input
  • Set Secure, HttpOnly, SameSite cookies; strict CORS
  • Log access-control failures and alert
  • Test every role (horizontal & vertical) in CI/CD

๐ŸŒ Real-World & Pitfalls

It bites the biggest names: Facebook's 2018 access-token flaw exposed ~50M accounts (later a $5B FTC settlement), and Equifax's 2017 breach exposed ~147M records.

Common pitfall: Hiding a button or link in the UI is not access control โ€” the endpoint is still reachable. Enforce authorization on the server, for every request, not just on page render.

๐Ÿ” Tools & Takeaway

Burp Suite OWASP ZAP Postman Selenium pytest Flask-Login
Key Takeaway: Enforce access control on the server for every request, default to deny, and verify ownership. Never rely on hidden UI, client-side checks, or obscure URLs for security.