In this lesson, we will talk about what Broken Access Control issues are and how to identify them in web applications. At the end of the lesson, we will have some fun hacking a real web application using the gathered knowledge. Let's get started.
Permissions and privileges
Before diving deep into the actual vulnerability, let's first introduce the concept of permissions & privilege! If you are familiar with this topic and how they are implemented in web applications, feel free to skip this part.
In computer security, the terms permission and privilege are used interchangeably. A privilege is permission to perform an action. For instance, when we say that User A can read and write files in the Home folder, we are actually saying The privilege of User A is the permission to read and write files in the Home folder.
Most of the web applications that we use nowadays imply some sort of restrictions based on permissions. In a forum, for instance, some users are administrators and have the ability to view, edit or delete all posts, while regular users can only view all posts but not edit or delete them.
When the restrictions are not consistently implemented, they can lead to critical Broken Access Control issues. In 2015, Laxman Muthiyah discovered such a vulnerability in Facebook. The issue allowed him to become the admin of any Facebook business page by sending a simple HTTP request:
POST /<page_id>/userpermissions HTTP/1.1
Host : graph.facebook.com
role=MANAGER&user=<target_user_id>&business=<associated_business_id>&access_token=<application_access_token>
The vulnerability that Laxman Muthiyah identified is a perfect example of a Broken Access Control. Through that issue, an attacker could have escalated their privileges on the platform to access and modify data belonging to other users.
Now, to understand how this vulnerability occurs, we need to understand access control models and how they integrate within web applications.
What are Access Control Models
In the previous lesson, we introduced the concept of access control, commonly known as authorization. There we said that "an access control is a security mechanism that controls access to systems and resources. Its purpose is to protect information from being accessed, deleted, or modified intentionally or accidentally by those not authorized to do so". Simply put, the access control determines what users can (or can't) access.
A common requirement for applications, especially web-based ones, is that a user can only perform an action if a given set of conditions are satisfied. Here are just a few examples:
- Internet Forum: only members can post new messages or reply to existing ones
- E-commerce site: a regular user can only see their own orders
- Digital wallet: payments are limited to $500 from 20:00 to 08:00 in the user's time zone
Usually, these access control rules are decided during the design phase, when developers, engineers, and architects work together to establish the functional and security requirements of the app. At this stage, it is also important to decide what access control model to use, as the model will help developers implement robust and secure access control checks. A model in this context is the abstract foundations upon which actual access control mechanisms are built. You can think of it as a blueprint.
We can categorize Access Control Model into three main types:
- Discretionary access control (DAC)
- Mandatory access control (MAC)
- Role-based access control (RBAC)
We will discuss each of them later—but for now, keep in mind that there are three main types that most applications use.
All access control models are built on the relationship between two key parts:
- Subjects: These are the "who" - like you, other users, or groups of users
- Objects: These are the "what" - the things that need protection, like files or devices
Here's a simple example to make it more clear: think about Netflix profiles in a family account. When a teenager (the subject) tries to watch an R-rated movie (the object), Netflix checks if their profile has permission to view that content. If they're set up with a teen profile, the system will block access to that movie. The system is constantly checking "Does this person have permission to access this thing?"
What are Broken Access Control issues?
All right — so now that we clarified what an access control is and how it works, we can finally talk about how hackers take advantage of misconfigured access controls.
We can define Broken Access Control as a class of web vulnerabilities that allow an attacker to access resources or perform actions they shouldn't be allowed to. Most of the issues of this kind are fairly easy to identify as they do not require in-depth technical knowledge of a specific technology but rather a good understanding of the CIA model.
Bugs, bugs, bugs...
In programming, there are three types of errors that can occur:
- Syntax errors
- Runtime errors
- Logic errors
A syntax error occurs when the code written by the programmer doesn't follow the syntax rules of the programming language—for instance, misspelling a statement name (whil instead of while) or missing a closing bracket. Fortunately, the compilerA compiler is a program that translates code - typically from human-readable source code into machine code that computers can execute. throws a syntax error pointing out the problem to the developer. Therefore, they are fairly easy to identify and fix.
A runtime error occurs while a program is running or when you first attempt to start the application. They happen when the code is syntactically correct but contains an issue that is only detected during program execution. For instance, if the application tries to access the fourth item in a list containing only three items, it will result in a runtime error that will likely crash the application. Similar to syntax errors, runtime errors are easy to identify and fix.
Now the big boss of errors: the ⭐ logical error ⭐. Logical errors occur due to failing to anticipate the edge-cases of a program. They are mistakes in reasoning and not in the syntactic correctness of the code itself. Unlike a syntax error, a logic error does not usually stop a program from running. The program will run but operate incorrectly or behave abnormally.
Logic errors are called bugs, and they're much more interesting (but subtle) to resolve than syntax errors (typically called crashes). They are pretty much the reason why testing jobs exist 🤯
Logical errors are troublesome. As a programmer, they are challenging to identify and fix, since they don't produce an actual error. While some logical errors can be spotted just by eyeballing the code, many of them stay "invisible" for a long time as they cannot be detected by automated tools that check the correctness of the code.
Sometimes, logical errors can even cause security vulnerabilities! One such example is Broken Access Control — the topic of this lesson. Triggering a Broken Access Control issue won't result in an error — as it happens for other types of web vulnerabilities like SQL Injection or Cross Site Scripting. Instead, an attacker may silently access files or functionalities they should't be able to by interacting with the application in ways that developers never intended.
Access control issues are typically not detectable by dynamic vulnerability scanning and static source-code review tools, since they require understanding of how certain pieces of data are used within the web app. For this reason, they are incredibly widespread featuring the first place in OWASP Top 10The OWASP Top 10 is a standard awareness document for developers and web application security. It represents a broad consensus about the most critical security risks to web applications. most common web vulnerabilities.
Identifying Broken Access Controls - hands-on exercise
Now let's get some hands-on exeprience identifying a Broken Access Control vulnerability in an actual web application.
Why Broken Access Control issues occur?
That was a fun hands-on exercise, wasn't it?
But now you probably ask yourself: if it's that simple to identify a Broken Access Control vulnerability, how can developers miss such obvious issues?
That's a good question. Looking at the problem from a micro perspective, we can simply say: a Broken Access Control issue occurs when a developer forgets to add access control checks. But that would be a naive answer. Let's zoom out a bit and look at the big picture — the Software Development Process. Can we identify any pitfalls in the process that might "help" a developer forget or misimplement an authorization check?
Well…yes. Many reasons make Broken Access Control hard to spot while developing the app. Let's discuss the most important of them (in no particular order).
Poor planning
Imagine this...
It's 1887 in Paris, a period characterized by regional peace, harmony, stability, and prosperity. You are working for a construction company that just won a life-changing contract to build one of the world's most iconic monuments: the Eiffel Tower. "Now, what's the next step?" your boss asked.
Would your answer have been, "Oh, I know—I'll call our suppliers, buy an obscene amount of steel, and we'll start building this thing."? Probably not—or at least, I hope so. Instead, you would probably have come up with a plan!
Just like in the above example—and pretty much every other aspect of our life—planning is essential. And software development makes no exception to this rule. Every application should start with a design phase where developers, engineers, and architects work together. The goal of this phase is to establish the functional and security requirements of the app.
The truth is many web applications don't go through a (proper) design phase. As such, their functionalities and access controls were not deliberately designed but have simply evolved along with the app. In these cases, access control rules are introduced when needed, often in various places in the code. This approach makes spotting potential Broken Access Control issues even more complex and the codebase hard to maintain.
Generally speaking, well-designed applications have a centralized authorization class responsible for determining if a user has access to specific resources or functionality.
If APIs are poorly designed, they will implement checks on a per-API basis, manually reproducing authorization functionality. Suppose you can tell that an application reimplements authorization checks in each API. In that case, that application will likely have several APIs where the checks are not sufficient simply due to human error.
Complexity + human err = love
Even when the application goes through a proper design phase, there are still some other pitfalls that can make an application vulnerable to Broken Acess Control. Complexity, combined with humans being prone to error, is one of those pitfalls. In complex web applications, the design and implementation stages rely on various
And that may sound easy. In fact, for simple applications, it is! But in complex apps such as SaaS platforms with multiple user roles and hundreds of endpoints, each having its individual access control needs, ensuring the tech stack is watertight and has no room left for hackers is time-consuming and deceptively complex.
Blindly trusting other components
Another common cause for Broken Access Control issues in well-designed apps is simply trusting other components. Let's take the following diagram to illustrate the concept.

So here we have two components: A, a proxy, and B, a component of an app that should is responsible for the media logic.
Now, a common mistake in such architectures is to consider that the most likely source of trust is another element. This means that the developers of component A will trust component B to perform authorization checks since A is just a proxy. But also, developers of component B will rely on component A to perform the authorization checks since B is not the storefront of the application.
Simply put, anyone assumes someone else already did the validation, and thus, the validation never occurs, leaving the application vulnerable.

It is nothing wrong with component A performing authorization checks, as it is nothing wrong with component B performing them. It's just a design decision. But this decision needs to be clearly communicated to both development teams (A and B) for consistent and secure implementation of the access controls.
Difficult to detect with automated tools
As if all the reasons we mentioned aren't enough, here is another one.
Development tools like linters, static analysis, or dynamic scanners do a great job when it comes to identifying syntax errors or even insecure usage of various programming functions.
But Broken Access Control issues are logical bugs that do not produce syntax errors. They are typically not detectable by dynamic vulnerability scanning and static source-code review tools as they require an understanding of how certain pieces of data are used within the web app. Manual testing is the best way to detect missing or broken access controls.
Conclusion
In this lesson we've explored one of the most critical aspects of web security: access controls. You've not only learned about the theory behind permissions and access control models but also gained hands-on experience by discovering a real insecure direct object reference vulnerability. This practical experience is invaluable – it's one thing to read about vulnerabilities, but it's another to actually find them in action.
Remember, broken access controls consistently rank among OWASP's top web vulnerabilities because they're both common and potentially devastating. As you continue your security journey, you'll find that many data breaches started with a simple access control failure – whether it's a user accessing another user's data through URL manipulation or an unauthorized user bypassing authentication checks.
The skills you practiced in the lab will serve you well whether you're developing applications (where you'll need to implement proper access controls) or testing them for security vulnerabilities. Keep experimenting, keep testing, and most importantly, always think about how permissions could potentially be bypassed in any system you encounter.
Next up, we'll explore another type of issue called Open Redirect. There we'll see how even a basic redirect function can become a security nightmare if not implemented correctly. See you there!