Broken Access Control: OWASP #1 Risk Explained (2026)

Web Security
14 min read
Broken Access Control: OWASP #1 Risk Explained (2026)
On this page
  1. What Is Broken Access Control?
    1. Where It Shows Up
  2. How a Broken Access Control Attack Works
  3. Types of Broken Access Control
    1. Insecure Direct Object Reference (IDOR)
    2. Vertical Privilege Escalation
    3. Horizontal Privilege Escalation
    4. Forced Browsing and Missing Function-Level Control
    5. Metadata and Method Tampering
  4. IDOR: The Most Common Access Control Flaw
  5. How to Test for Broken Access Control
  6. How to Prevent Broken Access Control
  7. Broken Access Control in the OWASP Top 10
  8. Legal and Ethical Considerations
  9. Frequently Asked Questions
  10. Your Next Steps

Broken access control is the flaw where an application lets you do things it should have stopped you from doing: reading another user's data, hitting an admin page you were never granted, or editing a record that belongs to someone else. It sits at number one on the OWASP Top 10 because it is both everywhere and easy to miss. The fastest way to understand it is to break one yourself, so open HackerDNA's IDOR Explorer lab and change an ID or two as you read.

This risk earned the top slot in the OWASP Top 10 and kept it in the 2025 edition, which even folded Server-Side Request Forgery in as a sub-case. This guide covers what broken access control is, the main types you will meet (including IDOR), how the attack works step by step, how to test for it, and how to shut it down in your own code.

TL;DR: Broken access control happens when an app authenticates a user but never checks whether that user is authorized for the specific action or record they requested. The most common form is IDOR: swap id=1043 for id=1044 and read a stranger's invoice. The fix is not a better filter, it is a server-side authorization check on every request, tied to the logged-in user, denying by default. You learn to spot it by exploiting it, so practice in a browser lab before you try to defend against it.

What Is Broken Access Control?

Broken access control is a web vulnerability where an application does not correctly enforce what an authenticated user is permitted to see or do. The user logs in fine, but the app then trusts them with data or actions that should be restricted, because the authorization check is missing, weak, or applied in the wrong place.

The key distinction is authentication versus authorization. Authentication answers "who are you?" and most apps get it right. Authorization answers "are you allowed to do this specific thing?" and that is where they fail. An app can know exactly who you are and still hand you the admin dashboard because nobody wrote the check that says you are not an admin.

That gap is why this class is so common. Login systems get hammered on by every developer and every scanner. The per-object, per-action permission checks are scattered across hundreds of endpoints, and it only takes one endpoint that forgot to ask "does this record belong to the caller?" to leak the whole table. OWASP's data backs this up: broken access control was found in more tested applications than any other category, which is exactly why it ranks first.

Where It Shows Up

  • Object references - URLs and API calls that carry a record ID (/account?id=17) the server trusts without checking ownership.
  • Admin and privileged functions - management endpoints that rely on a hidden link rather than a real role check.
  • API endpoints - REST and GraphQL routes that enforce access in the UI but not on the server, so a direct request walks straight past it.
  • Static and internal resources - files, reports, and backups reachable by guessing a path the menu never linked.

How a Broken Access Control Attack Works

A broken access control attack has three moving parts: a valid session, a reference or action you are not supposed to control, and a server that checks identity but not permission. The flow is short.

  1. Log in as a normal user. You need a legitimate session to reach authenticated features. This is not an authentication bypass, you are an ordinary user abusing what you can already touch.
  2. Find a reference you can change. Look for an ID, username, filename, or role value in the URL, a cookie, a hidden form field, or a JSON body. Anything the client sends that the server acts on is a candidate.
  3. Change it and watch the response. Increment the ID, swap your username for another, flip role=user to role=admin. If the server returns data or performs an action that should have been denied, the access control is broken.

Consider an app that serves your profile at GET /api/user/2001/details. The server confirms you are logged in, then returns whatever user ID is in the path. Send GET /api/user/2002/details and, on a vulnerable app, you get the next person's details. You never broke the login, you just asked for something you should not have been allowed to have, and the server said yes.

When testing real applications, the first thing worth doing is capturing two accounts. Log in as user A, record a request that touches A's data, then replay it with A's session but B's identifier. If A can read or change B's resources, you have a confirmed access control flaw with a clean, repeatable proof, which is exactly what a report needs.

💻
Practice this now: IDOR Explorer lab - a document manager hands out files by sequential ID, and your job is to reach the ones that were never meant for you. Browser-based, no setup.

Types of Broken Access Control

Broken access control is a category, not a single bug. These are the forms you will actually run into, roughly in order of how often they turn up in real testing.

Insecure Direct Object Reference (IDOR)

An IDOR exposes an internal reference (a database ID, filename, or key) and lets a user swap it for one they do not own. It is the poster child of this category and gets its own section below because it is so common.

Vertical Privilege Escalation

This is a low-privilege user reaching high-privilege functions. A regular account that can load /admin/users or call an admin-only API is escalating vertically, moving up the permission ladder to actions reserved for a higher role.

Horizontal Privilege Escalation

Here you stay at the same privilege level but reach a peer's data. User A reading user B's messages is horizontal escalation. Most IDORs are horizontal: same role, different owner, no check that the owner is you.

Forced Browsing and Missing Function-Level Control

Some apps hide a page by simply not linking to it, assuming nobody will find the URL. That is security by obscurity, and it fails the moment someone guesses /admin, reads it in JavaScript, or finds it in the sitemap. If the server does not check the role when the page loads, the hidden link was the only lock.

Metadata and Method Tampering

Access decisions built on client-controlled data break when the client changes that data. A JWT with "role":"user" that the server trusts without verifying the signature, a X-Original-URL header that reroutes around a path check, or an endpoint that blocks POST but not PUT are all access control failures dressed up in protocol details.

IDOR: The Most Common Access Control Flaw

Insecure Direct Object Reference (IDOR) is a broken access control flaw where an application uses a user-supplied value to fetch an object directly, without checking that the requester is allowed to access that object. Change the value, get a different object. It maps to CWE-639 and is the single most reported form of access control failure in bug bounty programs.

The classic case is the invoice. You view your own at /invoice?id=1043, change the number to 1044, and the app hands you someone else's, because it verified you were logged in but never verified that invoice 1044 was yours. The same shape appears with usernames (/profile/alice becomes /profile/bob), filenames (/download?file=report_2024.pdf), and API paths (/api/orders/58210).

IDOR is dangerous precisely because it is boring to exploit. There is no clever payload, no encoding trick, no race condition. You increment a number. That low bar is why automated ID enumeration through a tool like Burp Intruder can pull thousands of records from a single vulnerable endpoint in minutes, and why an IDOR on a sensitive object is often triaged as high or critical severity.

A common defense you should not trust is swapping sequential IDs for UUIDs. Random identifiers make guessing harder, which raises the bar, but they are not authorization. If a UUID leaks through a referrer header, an export, or a shared link, and the server still does not check ownership, the IDOR is intact. UUIDs are a speed bump, not a control.

💻
Take it further: Admin Portal Breach - escalate from a normal account to full admin access by exploiting a missing function-level check, the vertical-escalation cousin of IDOR.

How to Test for Broken Access Control

How do you test for broken access control? Log in with two separate accounts, capture the requests one account makes to its own resources, then replay those requests using the other account's session and someone else's identifiers. If the server returns data or performs actions it should have blocked, access control is broken. Automated scanners miss most of these, because only a human knows which record should have belonged to whom.

A practical methodology looks like this:

  • Map every role. List the privilege levels (anonymous, user, admin) and get a test account for each. Access control is relative, so you need something to compare against.
  • Catalog the references. Walk the app with Burp Suite's proxy running and note every ID, username, filename, and role value the client sends. Each one is a test case.
  • Swap and replay. Take a request from account A and reissue it with A's session but B's identifier. Then try it with no session at all. Watch for a 200 where you expected a 403.
  • Test the methods and the UI gaps. If POST /admin/delete is blocked, try PUT or DELETE. If a button is greyed out client-side, send the request the button would have sent anyway.

In practice, the finding that surprises teams most is the "hidden" admin API. The front end never shows the control to a normal user, so everyone assumes it is safe, but the endpoint answers a direct request from any logged-in account. The UI was doing the access control the server forgot to do. That is the everyday face of this vulnerability.

How to Prevent Broken Access Control

How do you prevent broken access control? Enforce authorization on the server for every request, deny by default, and tie each access decision to the authenticated session rather than to any value the client sends. Never rely on hiding a link or disabling a button, because the client is fully under the attacker's control.

Layer these controls, since access control is a discipline rather than a single fix:

  • Deny by default. Every resource starts closed. Access is granted only by an explicit rule, so a new endpoint someone forgot to protect is locked, not open.
  • Check ownership on the server, every time. Before returning object 1044, confirm the current session owns object 1044. Do this in the backend, on every request, not once at the gateway. This is the control that actually stops IDOR.
  • Never trust client-side identity. Derive the user from the server session, not from a URL parameter, hidden field, or unverified token. If a JWT carries a role, verify its signature before you believe a single claim in it.
  • Centralize the logic. One authorization layer that every request passes through beats per-endpoint checks copied by hand, because the copies drift and one of them will be wrong.
  • Log access failures and rate-limit. A flood of 403 responses across incrementing IDs is an enumeration attack in progress. Record it and throttle it.

The mitigation teams most often get wrong is checking access at the wrong layer. A gateway that confirms you are logged in is not the same as a service that confirms you own the record, and putting the only check at the edge leaves every internal call unguarded. Validate ownership where the data is served, tied to the session, and the whole class largely closes.

Broken Access Control in the OWASP Top 10

Broken access control has been the number one entry since the 2021 edition and held that position in the OWASP Top 10 2025. It ranks first on the data: OWASP found some form of access control weakness in a larger share of tested applications than any other category, and the impact ranges from reading one extra record to full administrative takeover.

The 2025 revision made the category broader. Server-Side Request Forgery, which had its own tenth slot in 2021, was reclassified as a sub-case of broken access control, on the reasoning that SSRF is fundamentally the server making a request it was never authorized to make. If you want the SSRF angle specifically, our SSRF attack guide covers the cloud-metadata and internal-service targets that make it dangerous.

For the full map of where this risk sits among the ten and what shifted between the 2021 and 2025 lists, our OWASP Top 10 guide walks every category with a worked example. Access control failures also overlap with injection flaws in practice, so it is worth reading alongside our SQL injection tutorial, where a single query can dump records no user should reach.

Critical reminder: Always get explicit written authorization before testing any system for broken access control. Changing an ID to read another user's data on a target you do not own is unauthorized access under the Computer Fraud and Abuse Act (US), the Computer Misuse Act (UK), and equivalent laws worldwide, even when the change is as small as typing a different number.

  • Test only on systems you own, in dedicated labs, or within the defined scope of an authorized engagement.
  • An IDOR that returns real user data means you have accessed someone else's personal information. Stop at proof of impact, do not download at scale, and report it immediately.
  • "The URL let me" is not a legal defense. Authorization is about permission from the owner, not about whether the server happened to answer.
  • Practice on intentionally vulnerable targets, not live applications you stumbled onto. The labs below exist for exactly this.

Frequently Asked Questions

What is broken access control in simple terms?

Broken access control is when an app lets a logged-in user do something they should not be allowed to do, like viewing another person's account or reaching an admin page. The app checks who you are but forgets to check whether you are permitted to perform that specific action, so it hands over data or powers that should be restricted.

What is the difference between broken access control and IDOR?

Broken access control is the broad category of authorization failures. IDOR (Insecure Direct Object Reference) is one specific type within it, where changing a reference like an ID or filename gives you access to an object you do not own. Every IDOR is a broken access control flaw, but not every access control flaw is an IDOR.

Why is broken access control number one on the OWASP Top 10?

OWASP ranks it first because its data showed some form of access control weakness in a larger share of tested applications than any other category, and the impact is high. A single missing authorization check can expose every record in a table or grant full administrative control, and these checks are spread across so many endpoints that one is almost always forgotten.

How do you prevent broken access control?

Enforce authorization on the server for every request, deny access by default, and base each decision on the authenticated session rather than on values the client sends. Check that the logged-in user owns the specific object before returning it, centralize the logic in one layer, and never rely on hidden links or disabled buttons, which the client can bypass.

Do UUIDs prevent IDOR?

No. Replacing sequential IDs with random UUIDs makes references harder to guess, which slows enumeration, but it is not an authorization check. If a UUID leaks through a link, export, or referrer header and the server still does not verify ownership, the IDOR remains exploitable. UUIDs are a speed bump, not a control.

Related articles:

Your Next Steps

Broken access control clicks the moment you exploit one yourself: change a single number, watch a stranger's data load, and the reason it tops the OWASP Top 10 stops being abstract. Reading that authorization should be checked server-side is one thing, seeing an app forget to and hand you the admin panel is another. Start with HackerDNA's free tier, no credit card required, and reach files that were never meant for you in the IDOR Explorer lab. When you want access control in the context of the full attack surface, the Web Attacks course walks through it alongside SQL injection, XSS, and the rest of the OWASP Top 10 in guided browser labs. Learn to spot the missing check, then go write the one that stops it.

HackerDNA Team

HackerDNA Team

Written by the HackerDNA team - cybersecurity professionals building hands-on hacking labs and educational content to help you develop real-world security skills.

Meet the Team

Ready to put this into practice?

Stop reading, start hacking. Get hands-on experience with 170+ real-world cybersecurity labs.

Start Hacking Free
15,000+ Hackers 100+ Labs & Courses Free
Start Hacking Free