Disclaimer: I'm currently learning web security through OWASP and PortSwigger Web Security Academy. These are my beginner-friendly notes rewritten as a blog to help reinforce my understanding. If you're just starting out, I hope this makes the topic easier to understand.
What you'll learn:
In this article you'll learn:
✔ What Broken Access Control is
✔ Vertical Privilege Escalation
✔ Security by Obscurity
✔ Parameter-Based Access Control
✔ Platform Misconfiguration
✔ Horizontal → Vertical Escalation
✔ IDOR
✔ Lessons learned from PortSwigger labs
Concept Map:
What is Broken Access Control?
Broken Access Control happens when a user is able to access data, pages, or perform actions that they are not supposed to.
Why should you care?
Broken Access Control has ranked #1 in the OWASP Top 10 (2021) because it can expose sensitive data, allow privilege escalation, and let attackers perform actions they should never be able to perform.
Think of a website with two types of users:
- Normal User
- Admin
A normal user should only be able to view their own profile and perform basic actions.
An admin, however, can manage users, delete accounts, change settings, etc.
If a normal user somehow gains access to those admin features, that's Broken Access Control.
In interview terms:
Broken Access Control is the failure to properly enforce authorization, allowing users to perform actions beyond their intended permissions.
1. Vertical Privilege Escalation
Vertical Privilege Escalation means moving up the permission hierarchy.
Example:
Normal User
↓
Admin
A normal user should never be able to become an administrator.
1.1 Unprotected Functionality
One of the simplest forms of Broken Access Control is Unprotected Functionality.
Imagine a website has an admin page:
/admin
The developer removes the Admin button from the normal user's dashboard.
Problem solved?
No.
If a user manually visits:
/admin
and the server doesn't verify whether they're actually an admin, the page opens.
The mistake here is relying on the user interface instead of enforcing authorization on the server.
Attacker's mindset
When testing a website, an attacker may ask:
- Can I manually visit hidden pages?
- Can I guess common admin URLs?
- Can I inspect
robots.txt? - Can I brute-force directories?
PortSwigger Lab
In the lab, the admin panel wasn't linked anywhere.
However, visiting:
/robots.txt
revealed:
/administrator-panel
Opening that URL directly gave access to the admin panel, where I was able to delete the user carlos.
Key takeaway
robots.txt is public.
Hiding an admin URL is not the same as protecting it.
The server must always verify permissions before allowing access.
1.2 Security by Obscurity
Sometimes developers try to make admin pages "secret" by giving them strange URLs like:
/administrator-panel-yb556
This is called Security by Obscurity.
The idea is simple:
"If attackers can't guess the URL, they can't access it."
Unfortunately, that isn't real security.
The hidden URL may still appear inside:
- JavaScript files
- HTML source code
- Network requests
Anyone can inspect these using the browser's Developer Tools.
Once the URL is discovered, if the server doesn't perform authorization checks, the page becomes accessible.
Key takeaway
A hidden URL is not a protected URL.
Always implement proper server-side authorization.
1.3 Parameter-Based Access Control
Some applications make another dangerous mistake.
Instead of storing a user's role securely on the server, they store it somewhere the user can modify.
Examples include:
- Cookies
- Hidden HTML fields
- URL parameters
- JSON request bodies
Imagine the application uses:
/login/home.jsp?admin=false
or
/login/home.jsp?role=0
If the server blindly trusts these values, an attacker can simply change them to:
admin=true
or
role=1
and gain administrator privileges.
This is why client-side data should never be trusted.
PortSwigger Lab 1 – Cookie Manipulation
In this lab:
- The admin panel existed at
/admin - Access was denied initially
Using Burp Suite, I intercepted the login response and found the cookie:
Admin=false
I changed it to:
Admin=true
After forwarding the modified response, I could access the admin panel and delete carlos.
What I learned
Cookies belong to the client.
Anything stored on the client can be modified.
The server should never trust role information stored in cookies.
PortSwigger Lab 2 – JSON Parameter Manipulation
This lab required users to have:
roleid = 2
I updated my email address while intercepting the request in Burp Suite.
Inside the JSON request body, I found my current role.
I modified it to:
"roleid": 2
After sending the modified request, my role changed to administrator.
I could then access /admin and delete carlos.
What I learned
Just because data is sent inside JSON doesn't mean it's secure.
If the server trusts user-controlled JSON values, privilege escalation becomes possible.
Final Thoughts
The biggest lesson from this learning was surprisingly simple:
*Never trust client-controlled data. Always validate authorization on the server or in simple words: Never trust anything coming from the browser *
Whether it's:
- a URL
- a cookie
- a hidden field
- a request parameter
- or a JSON value
all of them can be modified by an attacker.
The responsibility of deciding who is allowed to do what always belongs to the server.
That's the core idea behind preventing Broken Access Control.
Now that we've seen common authorization mistakes, let's look at another interesting case where access control fails due to platform misconfiguration.
1.4 Platform Misconfiguration and Access Control Bypass
Another interesting form of Broken Access Control happens because of platform misconfiguration.
This sounds complicated at first, but the idea is simple:
The website has security checks, but the security layer and the application do not interpret requests in the same way.
Imagine the application has a rule like:
DENY:
POST /admin/deleteUser
This means users should not be able to access that admin functionality.
Normally, a request looks like this:
POST /admin/deleteUser
The security layer sees the request and blocks it.
However, some frameworks support special headers such as:
X-Original-URL
X-Rewrite-URL
These headers can internally change where a request is routed.
An attacker may send:
POST /
X-Original-URL: /admin/deleteUser
Now something unexpected happens:
- Security layer sees:
POST /
- Application sees:
/admin/deleteUser
The security system thinks the request is harmless, while the application executes the admin functionality.
This can lead to access control bypass.
Another technique: HTTP Method Bypass
Sometimes security rules only restrict one HTTP method.
Example:
DENY:
POST /admin/deleteUser
Developers assume deletion will only happen through POST requests.
An attacker may test:
GET /admin/deleteUser?user=carlos
If the application accidentally accepts GET requests as well, the action still executes.
The security rule only checked:
POST
but the application accepted:
GET
What I learned
Security checks should not rely only on proxies, URLs, or request methods.
Authorization should always be validated on the server for every sensitive action.
The biggest takeaway:
If the security layer and application interpret requests differently, access control bypasses can happen.
2. Horizontal to Vertical Privilege Escalation
Earlier, we looked at Vertical Privilege Escalation, where a normal user directly gains administrator access.
But sometimes attackers take a different route.
They first compromise another user's account (Horizontal Privilege Escalation) and then use that account to become an administrator.
Imagine your account page is accessed using:
/myaccount?id=123
If the application doesn't verify ownership, an attacker might simply change the URL to:
/myaccount?id=456
If User 456 happens to be an administrator, the attacker now has access to an admin account.
In the PortSwigger lab using Burp Suite, changing the user identifier exposed the administrator's account page, which revealed the administrator's password. Using those credentials, I logged in as the administrator.
What I learned
Horizontal privilege escalation isn't always the final goal.
Sometimes it's just the first step toward gaining administrator privileges.
3. Insecure Direct Object References (IDOR)
An Insecure Direct Object Reference (IDOR) occurs when an application directly uses user-supplied input to access resources without checking whether the user is actually authorized to access them.
These resources (called objects) can include:
- User profiles
- Chat transcripts
- Documents
- Images
- Orders
- Database records
For example, suppose a chat transcript is stored as:
/download/2.txt
If I manually change it to:
/download/1.txt
and the server returns another user's transcript without checking ownership, that's an IDOR vulnerability.
The problem isn't that the URL can be changed.
The real problem is that the server trusts the user-supplied object reference without verifying whether the user should have access to it.
PortSwigger Lab
In this lab, chat transcripts were stored as text files with predictable names such as:
1.txt
2.txt
3.txt
After viewing my own transcript, I noticed the filename pattern.
I changed:
2.txt
to:
1.txt
The server returned another user's chat transcript, which contained Carlos's password.
I then used those credentials to log into Carlos's account.
What I learned
If an application exposes predictable object references without verifying ownership, attackers can access data that belongs to other users.
How to Prevent Broken Access Control
Most Broken Access Control vulnerabilities exist because the server trusts information that comes from the client.
Some simple security principles can prevent many of these issues:
- Deny access by default unless explicitly allowed.
- Perform authorization checks on the server for every request.
- Never rely on hidden URLs or secret page names for security.
- Verify that users own the resources they are trying to access.
- Use a centralized authorization mechanism across the application.
- Regularly audit and test access control rules.
Final Takeaway
Throughout these labs, one idea kept appearing again and again:
Never trust the client. Always enforce authorization on the server.
Whether an attacker modifies a URL, cookie, request parameter, JSON value, or filename, the server should always verify who is making the request and whether they are allowed to perform that action.
That's the foundation of secure access control.
References
- OWASP Top 10
- PortSwigger Web Security Academy (Broken Access Control labs)
Top comments (0)