APIs are becoming the wild-wild-west. What was once old is new again… where basic flaws in how user access is handled expose web applications and APIs to unnecessary risk through broken access control.
There are many ways to find access control issues in APIs. In this article, I’ll focus on three specific areas: weaknesses with role-level authorization, misuse of resource-level access, and abuse of field-level authorization.
Let’s get started!
Where to begin?
When you consider the OWASP API Security Top Ten, broken function level authorization (BFLA) is in the top 5 classes of vulnerability.
Complex access control policies with different hierarchies, groups, and roles, and an unclear separation between administrative and regular functions, tend to lead to authorization flaws.
By exploiting these issues, you as the attacker gain access to other users’ resources and/or administrative functions. It also serves as a great pivot point to escalate privileges as part of a more impactful kill chain.
There are really three key levels of user access control that you should look into when searching for authorization issues. Those are at the role level, the resource level, and the field level.
Role-based access control
At the highest level, during the initial recon of your target, you will have done a happy path execution to see how the web application functions. You will typically be able to determine different levels of access that the application holds. This might be as simple as normal users and administrators. Or could be a complex list of permissions and access rights or specific roles that allows different API users to use the system in entirely different ways.
Security teams commonly refer to this as role-based access control (RBAC).
What is RBAC?
Role-based access control (RBAC) is a security model that allows you to manage users and their permissions by assigning them to specific roles. A role can be defined as a collection of permissions that allow the user assigned to that role to carry out specific actions. RBAC provides an efficient way to manage users and their permissions, and it makes it easy to add or remove users from a particular role without having to modify the permissions assigned to that role.
How to test RBAC
Document every role the application uses
The first thing you want to do before testing RBAC is to understand the roles used in the application. Document what each user role has permission to do, and more importantly, what it’s NOT allowed to do.
Map roles to permissions
Once you know what every role does, map it to the permissions and/or features of the application. By doing this you can better understand the access control design decisions used to protect each API endpoint.
A key aspect you want to look for is how administrative access differs from normal user access. Are there separate API endpoints, or does the access control mechanism handle this through session management with things like an access control token (ie: JSON web token) or maybe through unique parameters?
And if there is an ability for an unauthenticated user to be able to make API requests, how does the authorization module of the web service deny access to those endpoints the user isn’t allowed access to without logging in?
By mapping each role to its individual permissions, you start to get a clear picture of how different users SHOULD and SHOULD NOT be able to use the API.
TIP: Use a spreadsheet. Define individual permissions by column and roles by row. Then map out which role has which permissions. As an example, I like to color code sensitive perms and quickly cross reference who has access to what, and when. This lets me quickly figure out which user roles I need to attack in my own accounts to get clear vertical privilege escalation for a feature I want to abuse, or users data that I want to access.
Determine how authentication and session management impacts access
You want to look at how the APIs identify users. Ask yourself these questions:
- Is it based on metadata in the request?
- Are roles defined in a claim of the access token?
- What about additional headers or parameters?
- How does a given user differ from other users?
- Is it based on a unique identifier?
By digging into how RBAC impacts things, you can start to think about broken access control in a clearer way. Example attack scenarios like metadata manipulation and parameter tampering come into focus and direct access to API endpoints allows us to validate if the principles of least privilege can be defeated.
Resource-level access control
During recon of your target web application, you will have hopefully mapped out which parts of the application require privileged access. From public resources like the login page to the different authenticated pages within the app itself, you can start to document the unauthorized functionality that you are denied access to until you pass specific access control checks.
You might even be able to observe missing access controls that let you access objects directly from a legitimate request. For example, you might find there are no authorization checks on the sign-in page, but all privileged pages require an authorization token in the request header. Or that to gain administrative access to the admin page you must have more than user roles.
Looking deeper at resource access
With APIs, there is more to this story. You want to explicitly see if API access grants you the capability to do even more. This is key to broken function level authorization vulnerabilities. As an example, can you modify the account information of another user in an account lookup tool by simply changing the HTTP method from a GET to a PUT? Can you read another user’s account when you aren’t supposed to?
As a standard user, can you gain horizontal privilege escalation into someone else’s account by simply manipulating insecure direct object references (IDOR), more commonly called broken object-level authorization (BOLA) in the API hacking world?
Privilege escalation to an admin context
Can you access administrative functions by simply knowing the administrative URL? Or can you gain access to admin rights by changing the internal application state?
While you might not have code-level access to the API, you can typically brute force this by tracking every HTTP request. A good attack tool like Burp can do this for you, but so too can your browser’s dev tools. I talked about recording this traffic and weaponizing it using HAR captures in a previous article.
Field-level access control
How well does the API handle unverified data? The OWASP API Security Top Ten covers an entire vulnerability class through mass assignment that exposes field-level access control issues.
Why mass assignment is so prevalent in APIs
In today’s modern web applications developers sometimes rely on software frameworks to automatically bind HTTP request parameters into program code variables or objects. This can sometimes cause harm.
As an attacker, you can use this methodology to potentially create new parameters that the developer never intended which in turn creates or overwrites new variable or objects in program code that was not intended.
Let me show you how.
How to exploit field-level access control flaws
If an API call blindly relies on user-supplied input it might be possible to escalate privileges by simply modifying the data sent to an appropriate API endpoint. As an example, if a field can be tampered with to alter the API’s behavior, it might be possible to change how the backend interprets things and expose a broken function-level authorization issue.
Imagine a user record that included the following fields:
- Email Address
Perhaps during user creation within the app, an administrator is asked if this new user is an admin as well. If so, they check the box, and ultimately that field is updated.
Now imagine that the developer added some functionality to allow users to update their account password. They probably aren’t going to expose the IsAdmin data in a hidden field, but instead will use partial updates, sending a data object with only some of the fields, like maybe the id and new password.
This is a potential attack vector. Because the developers rely on these programming frameworks you might be able to add the IsAdmin field to the POST or PUT HTTP method for the password update and overwrite the IsAdmin field and deliver privilege escalation for the user account.
Authorization issues in APIs are a goldmine for us on offense. They can be used to access sensitive data and perform unauthorized actions. In this article, we looked at just a few ways you can find and exploit access control issues in APIs.
Chaining together vulnerabilities like broken object-level authorization with broken function-level authorization and mass assignment gives us the greatest chance to reach the nirvana of vertical privilege escalation and hopefully full control.
If you’re looking to hack an API, these are some methods that you should keep in mind.
Want to learn more?
Found this article useful? Then make sure you grab my free Ultimate Guide to API Hacking Resources. I’ve included many of the useful resources I have found over the years that have helped me work on my API hacking tradecraft. Hopefully, they can help you too!