
Loading

Loading
We use strictly necessary cookies to run this site, and analytics cookies to understand how it's used. See our Privacy Policy for details.
Why broken access control has topped the OWASP Top 10 since 2021, and what an IDOR finding actually looks like when it shows up in a real assessment report.
Broken access control has held the top spot on the OWASP Top 10 since the 2021 edition, and remains there in the current 2025 edition, not because it's a new or exotic vulnerability class, but because it's the one that's hardest to catch with a scanner and easiest to introduce by accident. An application can pass every automated security test, have no SQL injection, no XSS, a clean dependency scan, and still let any logged-in user read or modify another user's data simply by changing a number in a URL.
The category is broader than one bug type, it's any case where the application fails to properly enforce what an authenticated user is allowed to do. That includes missing function-level authorization (a regular user hitting an admin-only API endpoint directly, because the endpoint checks that you're logged in but never checks which role you have), privilege escalation through parameter tampering, and CORS misconfigurations that let an unrelated origin make authenticated requests on a victim's behalf. Insecure Direct Object Reference, IDOR, is the specific, most common shape it takes in practice.
An IDOR is deceptively simple: an endpoint like /api/invoices/4521 returns invoice 4521 to whoever is logged in, with no check that the logged-in user actually owns invoice 4521. Change the number to 4522, and, if the check is missing, you're looking at someone else's invoice. The same pattern shows up as ?user_id=, /orders/{id}, /documents/{id}/download, or a GraphQL query that accepts an arbitrary object ID. It's called "insecure direct object reference" precisely because the object is referenced directly by a predictable or guessable identifier, with the authorization check assumed rather than actually performed.
A vulnerability scanner can fuzz inputs and watch for error messages, stack traces, and reflected payloads, all signals it's built to recognize. It has no way to know that invoice 4521 belongs to a different account than the one it's authenticated as, because that requires understanding the application's actual data model and business logic, not just its HTTP surface. Confirming an IDOR requires two authenticated sessions as two different users, and deliberately trying user A's session against user B's resource IDs, a scenario a scanner running as a single account can't construct on its own. This is exactly the kind of finding that needs manual testing, not just automated scanning, and it's a large part of why our API security assessments specifically test with multiple authenticated roles rather than one.
The only durable fix is enforcing authorization at the object level, on every request, server-side, checking not just "is this user logged in" but "does this specific user have rights to this specific resource", as close to the data-access layer as possible, not scattered across UI logic that can be bypassed by calling the API directly. Our Web & API Security Testing engagements test this specifically with multiple roles and accounts, and our Secure Code Review service looks for authorization checks that exist at the route level but not the object level, the exact gap an IDOR lives in. For the broader OWASP category this sits inside, see our OWASP Top 10 overview.
Tell us about your environment and goals, we'll help you scope the right engagement.