3. Mass assignment vulnerabilities
Mass assignment vulnerabilities
Mass assignment, aka auto-binding, can inadvertently create hidden parameters. It occurs when software frameworks automatically bind request parameters to fields on an internal object. Auto-binding may therefore result in the app supporting parameters that were never intended to be processed by the developer.
Identifying hidden parameters
Since auto-binding creates params from object fields, we can often identify these by manually examining objects returned by the API. For example, consider a PATCH /api/users/
request, which enables users to update their username and email, and includes the following JSON:
1
2
3
4
{
"username": "wiener",
"email": "wiener@example.com",
}
A concurrent GET /api/users/123
request returns the following JSON:
1
2
3
4
5
6
{
"id": 123,
"name": "John Doe",
"email": "john@example.com",
"isAdmin": "false",
}
This may indicate that the hidden id
and isAdmin
params are bound to the internal user object, alongside the updated username
and email
params.
Testing auto-binding vulnerabilities
We can test if we can modify the enumerated isAdmin
param value by adding it to the PATCH
request:
1
2
3
4
5
{
"username": "wiener",
"email": "wiener@example.com",
"isAdmin": false,
}
In addition, we can send a PATCH
request with an invalid isAdmin
param value:
1
2
3
4
5
{
"username": "wiener",
"email": "wiener@example.com",
"isAdmin": "foo",
}
If the app behaves differently, this may suggest that the invalid value impacts the query logic, but the valid value does not, which in turn, may indicate that the parm can be successfully updated by the user. We can send the PATCH
request with isAdmin
param value set to true
, to try and exploit the vulnerability:
1
2
3
4
5
{
"username": "wiener",
"email": "wiener@example.com",
"isAdmin": true,
}
If the isAdmin
value in the request is bound to the user object without adequate validation and sanitization, the user wiener
may be incorrectly granted admin privileges. To determine if this is the case, we can browse the app as wiener
to see whether we can access admin functionality.
Lab: Exploiting a mass assignment vulnerability
Objective: To solve the lab, find and exploit a mass assignment vulnerability to buy a Lightweight l33t Leather Jacket. You can log in to your own account using the following credentials:
wiener:peter
.
When we log in as
wiener
we can see the item’s initial price:If we add the jacket to our cart, go to checkout and place our order, we will notice that there is both a
GET
and aPOST
request to the/api/checkout
endpoint:The response to the
GET
request and thePOST
request itself have a similar parameter structure, but the former includes some additional parameters:In the
GET
request’s response there is a parameter calledchosen_discount
which includes apercentage
value, but on thePOST
request there isn’t. Thus, we can add it manually and set its value to100
:
Preventing vulnerabilities in APIs
When designing APIs, we must make sure that security is a consideration from the beginning:
- Secure your documentation if we don’t intend our API to be publicly accessible.
- Ensure our documentation is kept up to date so the legitimate testers have full visibility of the API’s attack surface.
- Apply an allowlist of permitted HTTP methods.
- Validate that the content type is expected for each request or response.
- Use generic error messages to avoid giving away info that may be useful for an attacker.
- Use protective measures on all API version, not just the current production one.
To prevent auto-binding vulnerabilities, we can allowlist the properties that can be updated by the user, and blocklist sensitive properties that should not be updated by the user.