October 2, 2026
Unpacking OWASP Top 10 A01 β Broken Access Control
Welcome to Day 2 of our Cybersecurity Awareness Month series. As promised, we are publishing a new blog every single day this month, eachβ¦
By OWASP PCCoE
7 min read
Welcome to Day 2 of our Cybersecurity Awareness Month series. As promised, we are publishing a new blog every single day this month, each written by a member of our team. Today, we are jumping straight into the big leagues: the absolute most common vulnerability on the modern web.
Introduction
Broken Access Control maintains a position of #1 in the OWASP Top 10 2025. This category has the highest number of occurrences in the contributed data, and the second-highest number of related CVEs(Common Vulnerabilities and Exposures). Notably, as of the 2025 update, Server-Side Request Forgery (SSRF) has been folded into this category, reflecting how heavily modern applications rely on proper access boundaries.
Access control enforces what data a user can access based on their Role (e.g., RBAC), ensuring they cannot act outside their intended permissions. Failure to do this can lead to cyberattacks and malicious actors taking advantage of these vulnerabilities.
The Core Concept: Authentication vs. Authorization
Before diving into the vulnerabilities, we have to clear up the most common point of confusion in access control:
β Authentication is the process of verifying who a user is (e.g., logging in with a username and password).
β Authorization is the process of verifying what they have access to (e.g., checking if that logged-in user is an Admin or a standard user).
Broken Access Control (BAC) happens when an application successfully authenticates a user but fails to properly enforce authorization.
Common Access Control Vulnerabilities
Privilege Escalation
β Vertical: A standard user finds a way to act as an admin.
β Horizontal: A user accesses data belonging to another user with the same privilege level.
Configuration and API Failures
β Unprotected Endpoints: API Endpoints that entirely miss access control checks, assuming that if a user can't see a button in the UI, they won't find the API route.
β CORS Misconfiguration: Overly permissive CORS policies that allow unauthorized third-party websites to make API requests on a user's behalf.
Client-Side Tampering
β URL Modification: Bypassing access control simply by modifying the path or parameters in the URL.
β Metadata Manipulation: Tampering with a JWT or hidden HTML fields to elevate privileges.
A Deep Dive into the Patterns
As APIs have become the backbone of modern web architecture, three specific patterns of broken access control have become notoriously prevalent:
β IDOR (Insecure Direct Object Reference): This occurs when an application exposes internal database keys or file names directly in parameters.
β Scenario: An attacker sees /download?file_id=101 in the URL, changes it to 102, and successfully downloads a confidential contract belonging to another company.
β BOLA (Broken Object Level Authorization): BOLA happens when an API verifies that a user is logged in, but fails to check if the user actually has permission to view or manipulate the specific object being requested.
β Note: BOLA is simply IDOR's modern API-era name; the underlying flaw is identical.
β Scenario: User A sends an API request to GET /api/financials/user_B_id and the server returns the data just because User A possesses a valid session token.
β BOPLA (Broken Object Property Level Authorization): This occurs when an application authorizes access to an entire object, but fails to restrict permissions on its individual internal fields or properties.
β Scenario: A user sends a PUT request to update their profile and includes an extra field: {"email": "me@test.com", "role": "admin"}. The backend blindly updates the entire object, granting the user administrative rights.
Practical Demonstration: PortSwigger Lab Walkthroughs
To understand how trivial these vulnerabilities can be to exploit, let's look at two practical examples. These scenarios are based on labs from the excellent PortSwigger Web Security Academy, and we highly recommend trying them out yourself.
Lab 1: Unprotected Admin Functionality (Vertical Privilege Escalation)
The Objective:
This lab demonstrates how a failure to protect sensitive routes can lead to malicious actors gaining complete administrative access. The goal is to find an exposed admin panel and delete the user carlos.
The Methodology:
Often, developers rely on "security through obscurity," assuming attackers won't find an admin panel if there are no public links pointing to it. However, sensitive paths are frequently leaked in files meant for search engine crawlers. By navigating to the site's robots.txt file (keeping in mind that robots.txt is simply a guide for polite web crawlers and not a security control), we can inspect the paths the application asks web crawlers to ignore.
The Exploit:
Reading the robots.txt file reveals a disallowed path: /administrator-panel. Because the application lacks authorization checks on this specific endpoint, any unauthenticated user who knows the URL can access it.
GET /administrator-panel HTTP/2 Host: vulnerable-website.com
The Result:
Navigating directly to /administrator-panel loads the full administrative dashboard.
From here, we can simply interact with the UI to delete the user carlos, successfully demonstrating severe vertical privilege escalation.
Lab 2: Insecure Direct Object References (Horizontal Privilege Escalation)
The Objective:
This lab shows how broken access control can lead to malicious actors extracting sensitive data and taking over other users' accounts via horizontal privilege escalation. The goal is to find a leaked password in a hidden chat transcript and use it to log in.
The Methodology:
While interacting with the application's live chat feature, there is an option to download the chat transcript. By intercepting this request using a proxy like Burp Suite, we can observe how the backend retrieves the file.
The Interception:
The intercepted HTTP request shows the application fetching the file by explicitly naming it in the URL:
GET /download-transcript/2.txt HTTP/2 Host: vulnerable-website.com
The Exploit:
The application directly references the object (2.txt) but fails to verify if the current session actually has the rights to view other files in that directory. We can modify the parameter to attempt to access older files belonging to other users. We change the requested URL to /download-transcript/1.txt.
The Result:
The server blindly trusts the modified request and returns the contents of 1.txt. The leaked transcript reveals a conversation where a user blatantly states their password in plain text:
CONNECTED: β Now chatting with Hal Pline β You: Hi Hal, I think I've forgotten my password and need confirmation that I've got the right one Hal Pline: Sure, no problem, you seem like a nice guy. Just tell me your password and I'll confirm whether it's correct or not. You: Ok so my password is [REDACTED]. Is that right? Hal Pline: Yes it is!
By extracting the leaked password, we can easily log into the victim's account (carlos), completing a full account takeover caused entirely by a lack of object-level authorization.
How to Test for Broken Access Control
β Change IDs: Swap out user, file, or transaction IDs in URLs and API requests to see if you can access others' data.
β Replay Requests: Capture an administrative request and try to replay it using a lower-privileged user's session token.
β Forced Browsing: Attempt to navigate directly to sensitive routes (like /admin or /api/v1/users) without logging in.
Prevention and Mitigation
Access control cannot be bolted onto an application as an afterthought. It must be woven into the architecture. Here is how to prevent these failures:
β Deny by Default: This is the golden rule. If a user does not explicitly have a rule granting them access to a resource, the system must deny the request. In code, this means routing all traffic through an authorization middleware that defaults to returning a 403 Forbidden unless a specific condition (e.g., @RequiresRole('admin')) is met.
β Verify Object Ownership: To fix IDOR/BOLA, you must check object ownership on every single request. For example, your database queries should look like SELECT * FROM data WHERE id = ? AND owner_id = current_user. Using unguessable IDs (like UUIDs) is merely defense-in-depth, not a fix β the missing authorization check is the actual bug.
β Use Allowlisted Fields (DTOs): To prevent BOPLA, use Data Transfer Objects (DTOs) or strict allowlists for updates so a client can never arbitrarily set sensitive fields like role.
β The Backend is the Source of Truth: Never trust inputs from the client. Hidden fields, URL parameters, or client-side UI toggles should never dictate authorization. The backend must always verify permissions against the database.
β Centralize Access Control: Implement your authorization logic in one centralized module and reuse it throughout the application. Do not rely on individual developers to manually write if(user.isAdmin) checks in every single API controller.
β Secure Your JWTs: Keep JWT access tokens short-lived to reduce the window of opportunity if a token is leaked. Always strictly verify the cryptographic signature on the backend and reject tokens using the alg: none header.
β Implement Rate Limiting and Logging: Attackers often use automated tools to guess IDs (like trying file_id 1 through 1000). Rate limiting slows down these enumeration attacks, while robust logging alerts administrators to suspicious patterns of failed access attempts.
The Takeaway
Broken Access Control remains the king of the OWASP Top 10 because it is fundamentally a failure of business logic, not just a simple typo. Automated security scanners struggle to detect it because a scanner doesn't know which users should be allowed to see which files. It is entirely up to developers and architects to design systems that verify not just "who you are," but "what you have the right to do" on every single request.
A friendly reminder: everything in this series is for learning. Only test systems you own or have clear permission to test.
Sources & References
OWASP Top 10: OWASP A01:2021 / 2025 β Broken Access Control
OWASP API Security Top 10: API1:2023 Broken Object Level Authorization (BOLA) & API3:2023 Broken Object Property Level Authorization (BOPLA)
PortSwigger Web Security Academy:
Lab: Unprotected admin functionality
Lab: Insecure direct object references
OWASP Prevention Guidance: OWASP Authorization & Access Control Cheat Sheet
Author: Om Khanjodkar (OWASP PCCOE Security Team)