Incorrect Authorization
Summary
This is CWE-863, a subtly different problem from a missing authorization check: here, the check genuinely exists and runs on every request, but its logic is wrong, so it produces an incorrect result under certain conditions. A common shape is an inverted or incomplete boolean condition, where a permission check that's meant to require a role to be present actually only excludes a couple of specific roles and defaults to allow for everything else, including roles that were never supposed to pass. Another common shape is a check that correctly verifies the user owns a resource of the right type, but never verifies it's this specific resource being requested. The bug isn't "there's no lock on the door," it's "there's a lock, but it doesn't actually distinguish between the right key and the wrong one."
Top Affected Components / Targets
- Role-based access checks implemented as an exclusion list (deny specific roles) rather than an allowlist (permit specific roles), which silently permits any role not explicitly named
- Multi-tenant applications where an authorization check confirms resource type and ownership pattern but not the specific tenant or object ID being requested
- Nested or inherited permission systems where a check at one level doesn't correctly propagate to a related sub-resource
Common Attack Vectors
- Systematically test every role or account tier against every protected action, rather than assuming a single test account's results generalize, since incorrect-logic bugs often affect only specific role combinations rather than all non-privileged users uniformly
- For resource-scoped actions, test whether the authorization check verifies the specific resource ID being requested, or only that a resource of the right general type and ownership shape exists somewhere
Common Payloads
- No single injected payload; the technique is systematic, authenticated testing across every role and resource combination the application defines, looking for the specific combinations where the logic gets it wrong
Detection Strategy
Authenticated testing across multiple distinct roles and account tiers, not just a single low-privilege account, is essential here, since the whole point of this category is that the check works correctly for most cases and fails only for specific combinations. Map every defined role and test each one against every protected action systematically, looking for the exact case where a role that should be denied is allowed through, or a role-appropriate action is scoped too broadly.
Tip: Testing tools that run these checks in parallel across every discovered endpoint can cut the time required substantially compared to fully manual testing, as long as they confirm findings with more than one signal to keep the false-positive rate down.
False-Positive Notes
A single successful unauthorized action from one account doesn't fully characterize the bug; documenting exactly which role or condition triggers the incorrect result (and confirming other, similar roles are correctly denied) helps distinguish a genuine logic bug from a one-off test artifact or a role that's intentionally more permissive than assumed.
How to Test
Manual Testing Methodology
Here is a systematic approach to identifying Incorrect Authorization vulnerabilities in a target application.
Before testing, map all input vectors that could be affected. Identify parameters, headers, cookies, and request bodies that interact with the vulnerable component. A proxy such as Burp Suite or OWASP ZAP, paired with normal browsing of the target, is usually enough to build this list.
Send a legitimate request and record the normal response: status code, content length, response time, and any identifying tokens. This baseline matters because it's what you'll compare later responses against once payloads are involved.
Inject test payloads into each identified input vector one at a time. Start with benign detection payloads before escalating to anything that could actually trigger the vulnerability. For Incorrect Authorization specifically, authenticate as a low-privilege test account, then substitute identifiers belonging to another account (sequential IDs, UUIDs harvested from other responses) into every request, and separately try reaching privileged endpoints/actions directly by URL or method regardless of what the UI exposes to that role.
Compare the response against your baseline, looking specifically for a 200 response containing another user's data, or a privileged action completing successfully, when the authenticated user should have received a 401/403 — compare against the expected-denial baseline for that same request from the same account.
Once a potential vulnerability is detected, confirm it with at least a few independent test cases to rule out coincidence. Document the exact request and response as proof. For Incorrect Authorization, a confirmed finding typically means showing that attacker-controlled input changes the application's behavior in a way that matters for security, not just that a payload was reflected somewhere harmless.
Real-World Impact
Real-World Impact
Broken access control and IDOR let attackers access or modify resources belonging to other users simply by changing an identifier, or by reaching an endpoint that should have required a higher privilege level. It's one of the most commonly reported vulnerability classes precisely because the underlying mistake is conceptually simple, yet easy to overlook in authorization logic that only checks whether a user is logged in, not whether they're entitled to the specific resource or action being requested.
Real-world exploitation ranges from reading other users' private messages, files, or financial records, to modifying account settings, to reaching admin-only functionality by requesting it directly regardless of what the UI shows. In multi-tenant applications, it can mean cross-tenant data access entirely. The severity scales directly with how sensitive the exposed resource or action is.
This bug class shows up in virtually every kind of application, from social platforms to banking APIs to healthcare systems, which makes it one of the more consistently valuable checks to run regardless of what the target actually does — and one of the hardest for an automated scanner to catch reliably, since confirming it requires understanding what a specific user should and shouldn't be able to reach.
Prevention & Remediation
Prevention and Secure Coding
Preventing Incorrect Authorization takes a defense-in-depth approach — no single control below is sufficient alone, but together they close off both the primary path and the most common bypasses.
Object-level authorization on every request. Verify the authenticated user actually owns or is entitled to the specific resource identified in the request — on every endpoint that accepts an identifier, not just the ones that seemed sensitive during development.
Centralize the authorization logic. Implement authorization checks in one shared layer or middleware instead of re-implementing them per endpoint; re-implementation is exactly where individual endpoints get missed.
Default-deny. Require an explicit permission grant for each action a role can take, rather than granting broad access and trying to enumerate exceptions.
Indirect references where feasible. Opaque, per-user tokens in place of sequential database IDs make horizontal enumeration harder, though this is a hardening measure, not a substitute for the authorization check itself.
Test authorization from the attacker's seat, not the developer's. Authenticate as a low-privilege user and attempt every action a higher-privilege or different-tenant user could take — the UI hiding a button is not an authorization control.