Part 6 of our OWASP API Security Top 10 Deep Dive Series
Here’s a simple question that reveals a dangerous assumption in modern software: Who decides what you’re allowed to do?
In the physical world, this question has obvious answers. Bank vaults have multiple locks. Military bases have armed guards. Executive boardrooms have key card access. The authority to grant or deny access is explicit, visible, and usually involves another human being making a conscious decision.
But in the digital world, we’ve built something unprecedented: systems that make split-second authorization decisions about millions of users, often with no human oversight whatsoever. We’ve essentially created automated gatekeepers that must constantly answer a crucial question: “Should this person be allowed to do this particular thing right now?”
The problem? Many of these digital gatekeepers are remarkably bad at their jobs.
Welcome to OWASP’s #5 API Security Risk: Broken Function Level Authorization. This vulnerability occurs when APIs fail to properly verify whether a user has permission to perform specific functions, like deleting records, accessing admin panels, or executing privileged operations. It’s the digital equivalent of a bouncer who checks IDs to confirm you’re old enough to enter the club, but then lets anyone walk behind the bar and start mixing drinks.
The Trust Architecture Built by Accident
To understand why this vulnerability is so pervasive, we need to examine a quirk of software development psychology. When engineers build APIs, they’re often thinking like helpful assistants, not security guards. The mental model goes something like this: “If someone knows how to call this function, they probably should be allowed to use it.”
This creates what we could call “implied permission architecture” – systems that assume good intentions and rely on obscurity rather than explicit authorization. It’s like having a filing cabinet where the locks are hidden under the handles rather than actually securing the drawers.
Consider this real-world scenario from the OWASP documentation:
A user registration system that only allows invited users to join.
The mobile app calls GET /api/invites/{invite_guid} to check invitation details. An attacker discovers they can simply change this to POST /api/invites/new and suddenly they’re creating admin-level invitations for themselves. The function existed, the API responded, and nobody checked whether this particular user should be creating invitations.
The API worked exactly as programmed. The business logic executed flawlessly. But the assumption that “only authorized users would know about this endpoint” proved catastrophically wrong.
The Hierarchy Illusion
Modern applications are built on complex webs of roles, permissions, and hierarchies – regular users, premium subscribers, moderators, admins, super-admins – each with distinct entitlements. But here’s where it becomes hard to comprehend: we struggle to think systematically about permission boundaries.
Research shows we design systems with the “happy path” in mind – assuming everyone follows the rules, while overlooking how those systems might be exploited by those intentionally breaking them.
This cognitive limitation manifests in several predictable ways:
The Method Switching Exploit: APIs that check permissions for GET requests but forget to check the same permissions for DELETE or PUT requests on the same resource. It’s like having a library that checks your ID when you want to read a book, but lets anyone delete the whole collection.
The URL Guessing Game: Administrative functions hidden behind predictable URLs like /api/admin/users/all or /api/v1/delete_everything, protected only by the assumption that regular users won’t discover these endpoints.
The Role Confusion Bug: Systems where the difference between user types is maintained on the client side or in easily manipulated tokens, rather than being verified server-side for every sensitive operation.
Digital Boundaries
Building strong function-level authorization means shifting from designing for compliance to designing for resistance. Ask “How do we help users do what they should?” AND “How do we stop them from doing what they shouldn’t?”
Default Deny Architecture: Sensitive functions must require explicit authorization, not just lack restrictions.
Role-Based Function Mapping: Map user roles to functions clearly. If you can’t diagram who can do what, your model is too complex to secure.
Consistent Enforcement Patterns: Run all authorization checks at the same architectural layer – middleware, decorators, or function calls – to avoid “forgot to check” issues.
Administrative Separation: Keep admin functions separate, with distinct authentication, security contexts, and audit trails.
The Behavioral Solution
The most effective path to solve broken function-level authorization is not through perfect technical design, but through organizational behavior that makes good authorization patterns inevitable.
Security-First Code Reviews: Train teams to ask “What authorization checks are happening here?” before asking “Does this code work?” Make permission verification as automatic as syntax checking.
Red Team Thinking: Regularly assign team members to actively try to break their own authorization systems. When developers think like attackers, they discover authorization gaps before real attackers do.
Permission Visualization: Create tools that make authorization relationships visible. If your team can’t quickly understand who can do what in your system, neither can your security model.
Failure Mode Practice: Conduct exercises where authorization systems are deliberately broken or misconfigured. Teams that practice responding to authorization failures get better at preventing them.
Intentional Permissions
The good news about broken function-level authorization is that it’s a design problem, not a technology one. Each case reflects a failure to translate human intention into system behavior.
When we build APIs that model human intention instead of relying on complex, self-enforcing permission systems, we create experiences that are both powerful and secure. And in a world where authorization mistakes have high stakes, that’s not just good engineering, it’s the foundation of digital trust.
Frequently Asked Questions About Function Level Authorization
Q: What’s the difference between authentication and function-level authorization?
A: Authentication asks “Who are you?” while authorization asks “What are you allowed to do?” Like a hospital: your ID gets you in (authentication), but doesn’t let you perform surgery unless you’re a surgeon (authorization). Many systems get the first part right but fail at enforcing role-based access.
Q: How common are broken function-level authorization vulnerabilities?
A: Very common. A large number of APIs have authorization flaws, often due to inconsistent logic and overlooked checks. Unlike authentication, these issues are subtle and can go undetected for months.
Q: Can you give a simple example of this vulnerability?
A: A regular user accesses GET /api/orders/123 to view their order. If they change it to DELETE /api/orders/123 and it works, they’re canceling someone else’s order. The system didn’t check if they were allowed to delete, just if they were logged in.
Q: What’s the easiest way to test my API for these issues?
A: Use “role switching.” Try accessing privileged functions from low-permission accounts. Also, test changing HTTP methods, GET to POST, PUT, and DELETE. Many flaws show up when you think like an attacker.
Q: Why don’t API gateways and firewalls catch these attacks?
A: Because the traffic is authenticated and looks normal. The problem lies in business logic, not network behavior, like a security camera seeing someone walk by but not knowing if they should be in that room.
Q: How do I fix authorization issues without breaking things?
A: Start with audit-only checks that log violations. Then tighten controls, focusing first on sensitive functions. Apply consistent patterns so new features include proper checks by default.
Q: What’s the relationship between this and privilege escalation?
A: Broken authorization often leads to privilege escalation, like a user accessing a “create admin” function. It starts with accessing the wrong function and results in a major compromise.
Q: How do microservices affect this risk?
A: Microservices complicate things; authorization may be needed across services, each making different assumptions. This leads to inconsistent security. Treat authorization as a cross-service concern.
Q: What role does API documentation play?
A: Poor docs worsen vulnerabilities. If required permissions aren’t clearly stated, developers guess. But overly detailed public docs can help attackers. Internally, documentation should be complete; externally, it should be limited.
Q: How does this relate to insider threats?
A: Over-privileged users may access sensitive functions without hacking. If an employee can export data or change user accounts just because the system doesn’t restrict them, that’s a serious risk. Proper authorization is key to mitigating insider threats