Let's be real — most mature web apps today have solid defenses against the classics like SQL injection and XSS..etc. Between modern frameworks, WAFs, and automated scanners, those bugs are getting harder to land. But Broken Access Control? That's a whole different game.
BAC isn't about bypassing filters — it's about slipping through logic gaps. It's the kind of vulnerability that hides in plain sight: a forgotten endpoint, a missing role check, a multi-step flow that assumes too much. And that's exactly why it's become one of the most exploited and rewarded flaws in bug bounty programs today.
In this writeup, I'll break down what BAC really means, how IDOR fits into the picture, and share some practical tricks and testing methodology to help you find and exploit these flaws — because once you understand how these bugs work, you'll see them everywhere.
🧭 What Is Access Control?
Access control is the mechanism that decides who can do what inside a web application. It governs which users can access specific resources, perform certain actions, or view sensitive data — based on roles, permissions, or context.
For example, it decides whether:
- A user can view another user's profile
- An endpoint is restricted to admins
- A low-privileged user can perform a restricted function meant for higher roles
🔓 What Is Broken Access Control (BAC) & IDOR?
Broken Access Control (BAC) happens when an application fails to properly enforce what a user is allowed to do. It's not about bypassing authentication — it's about performing actions or accessing data that should be restricted based on your role or context.
These flaws often show up when:
- Role checks are missing or weak
- Sensitive endpoints are exposed without proper validation
- The app assumes the frontend will enforce access rules
One of the most common BAC variants is IDOR — Insecure Direct Object Reference. This type of vulnerability arises when user-controlled parameter values are used to access resources or functions directly, without verifying whether the current user is authorized to access the referenced object.
For example:
- Changing
user_id=123
touser_id=124
in a request and getting someone else's data
These bugs are quiet. They don't crash the app. They don't throw errors. But they expose sensitive data, allow privilege escalation, and often lead to high-severity bounty payouts.
🧪 Methodology & Testing Tricks for BAC
Before diving into Broken Access Control testing, you need to set your mindset right. This isn't about throwing payloads — it's about understanding the app's logic, roles, and flow.
Start by observing what you're allowed to do and what seems restricted. Ask yourself:
- What actions can I perform as a logged-in user?
- What data can I access?
- What's blocked or hidden from me?
Then start mapping the roles. For example:
- Guest: Can browse public pages, maybe register
- User: Can access their own dashboard, profile, and basic features
- Admin: Can manage users, view sensitive data, or perform system-level actions
Your goal is to understand what each role is supposed to do — and then test what happens when you step outside those boundaries.
🔍 Recon Tips
- Crawl the app with different roles and compare behavior
- Inspect your Burp history for endpoints with juicy parameters like:
userId=
,orgId=
,username=
,role=
,accountId=
, etc.- Check the page source for hidden URLs or endpoints
- Look at
/robots.txt
for disallowed paths—sometimes they reveal internal routes
🧨 Testing Tricks & Payload Ideas
Header Manipulation
If you're blocked from accessing a URL, try bypassing with headers like:
GET /
X-Original-URL: /admin/deleteUser
Or:
GET /
X-Rewrite-URL: /admin/deleteUser
Some apps honor these headers due to reverse proxy setups.
URL Variants
Try different casing or extensions:
/ADMIN
,/admin/
,/admin.json
,/admin.xml
- Spring apps with
useSuffixPatternMatch
may treat/admin.anything
as valid
Referrer Spoofing
Some apps check if the request came from an internal page. Try:
Referer: /admin
Especially when accessing sensitive endpoints like /admin/deleteUser
.
ID Manipulation
If you see something like userId=123
, try changing it:
- To another number (
124
,999
, etc.) - To another username (
Pirlo → anotherUser
) - Even if the ID is unpredictable, try using one from another account or something leaked in the response
Role Tampering
If you spot a parameter like role=1
, try changing it:
role=2
,role=admin
,isAdmin=true
- Sometimes these values are echoed back in responses — try injecting them into update or login flows
Redirection Leakage
Even if tampering a userId
redirects you to the login page, inspect the response carefully. Some apps leak data during the redirect process—check headers, body, and any embedded info.
Step-Skipping Logic
Some apps enforce access control only on early steps. For example:
- Select user
- Confirm action
- Submit deletion
If step 3 doesn't revalidate access, you can skip steps 1 and 2 and directly hit the final endpoint with the required parameters.
🧠 Final Thoughts
Always remember that Broken Access Control isn't about using the same trick everywhere — it's about understanding the scenario, adapting your approach, and testing based on what the app exposes. Headers, role tampering, step-skipping, ID manipulation — they all depend on context. The more you observe, the more patterns you'll catch.
Here we've reached the end of this writeup. I hope you enjoyed it and found it useful ❤️
Feel free to connect with me on LinkedIn.