How misplaced trust quietly breaks authorization
Broken access control usually isn't caused by a missing if statement. It fails because applications trust the wrong things: hidden paths, client-controlled roles, headers, or the assumption that users will follow the intended flow. Once that trust crosses the system boundary, access control stops enforcing anything meaningful.
These examples come from practice labs, but the patterns aren't theoretical. The same mistakes appear in production systems where authentication already exists and access control is assumed to be solved. Looking at where trust is placed, rather than where checks are missing, explains why these failures keep slipping through and quietly compounding into real impact.
Trusting Obscurity
A common mistake is treating hidden functionality as protected functionality. If an endpoint isn't linked in the UI or is excluded through something like robots.txt, it's often assumed to be safe. It isn't.
Here, an administrative endpoint existed without proper authorization. Its only defense was obscurity. Once the path was discovered, the application made no attempt to verify whether access was allowed. The issue wasn't technical; it was conceptual. Hiding a path was mistaken for enforcing access.
Anything exposed to the client must be treated as attacker-visible. Without server-side authorization, obscurity only delays discovery; it doesn't prevent access.
Trusting Client Context
Access control breaks when applications let the client describe its own authority. Roles stored in cookies, role IDs passed in requests, or headers like Referer are treated as permission instead of untrusted input.
In these cases, authentication works, but authorization lives in the wrong place. The server accepts client-supplied context without validating it against trusted state, making privilege escalation trivial. Encoding and obfuscation don't change this. If the client can influence authorization decisions, access control becomes an honor system.
Trusting Flow Instead of State
Many applications assume that if a user reaches a certain step in a workflow, earlier checks must have already happened. Authorization is enforced at the start, then quietly dropped as the process continues.
Requests don't respect flow. They can be replayed, skipped, or reordered. When later steps fail to re-verify authorization or ownership, users gain access they were never meant to have. Redirects, blocked UI paths, or method restrictions don't matter if the backend still executes the action.
Authorization has to be enforced on every sensitive request. When access depends on how a user arrived rather than the current state, attackers don't break the system, they just walk around it.
Broken access control doesn't usually fail loudly. It fails through small trust decisions that seem harmless but aren't. Paths are hidden instead of protected, context is assumed instead of verified, and workflows are trusted more than state. When trust is treated as a boundary rather than something to enforce, access control looks correct right up until it breaks.