Modern application frameworks encourage developers to use functions that automatically bind input from the client into code variables and internal objects in order to help simplify and speed up development within the framework. Attackers can use this side effect of frameworks to their advantage by updating or overwriting properties of sensitive objects that developers never intended to expose. Mass assignment vulnerabilities are also sometimes referred to as autobinding or object injection vulnerabilities.
Exploitation of mass assignment vulnerabilities in APIs requires an understanding of the application’s business logic, objects relations, and the API structure. APIs expose their underlying implementation along with property names by design. An attacker can also gain further understanding by reverse engineering client-side code, reading API documentation, probing the API to guess object properties, exploring other API endpoints, or by providing additional object properties in request payloads to see how the API responds. APIs need to be exposed to some extent in order to enable functionality and data exchange. As a result, attackers are able to exploit mass assignment vulnerabilities more easily in APIs and API-based applications.
Objects in modern applications can contain many properties, some of which can be updated directly by the client such as user first name or address details, and other sensitive properties that should not, such as user access entitlements.
An API endpoint is vulnerable if it automatically converts client provided data into internal object properties without considering the sensitivity and the exposure level of these properties. Binding client provided data like JSON attribute-values pairs to data models without proper filtering of properties based on an allowlist usually leads to mass assignment vulnerability.
An attacker exploiting mass assignment vulnerabilities can update object properties that they should not have access to allowing them to escalate privileges, tamper with data, and bypass security mechanisms.
In the example above, the attacker has changed the API call to update their account, escalate their role and privileges to an “admin” role, and bypass single-sign on (SSO). If successful, the attacker can then perform actions within the application as an administrator.
In 2012, a security researcher by the name of Egor Homakov found a critical mass assignment vulnerability in GitHub’s public key form update function. This mass assignment vulnerability allowed any user to associate their public key to a given GitHub public or private repo and take ownership of that repo. The attack made use of one of GitHub’s public APIs to find the identifier ID for a given repo. An attacker could then pair this identifier with their own public key and submit the data to GitHub’s public key form update function to exploit the vulnerability.
Egor attempted to report the issue to GitHub prior to GitHub having a responsible disclosure policy. Egor felt his report wasn’t being taken seriously or being addressed quickly enough, and so he chose to exploit the vulnerability, taking ownership of the public rails repo hosted on GitHub to prove their point. This takeover activity and resulting swarm of comments is still visible in the rails git commit history. GitHub resolved the issue within roughly an hour after Egor’s exploit. The vulnerability was very simple to exploit, which may have been why it was so overlooked. It was also a catalyst for GitHub developing a responsible disclosure policy that still stands today, and which has evolved into GitHub’s public bug bounty program.
Traditional security controls like WAFs and API gateways lack context of API activity and intended business logic. They can’t know if the API caller in the example above should be able to send a request using the PUT method with additional parameters, failing to differentiate between a legitimate call and malicious activity. To these traditional controls, this API call looks normal. They lack the context to know that this user is not an administrator, and the user should not have access to these additional parameters. At best, a WAF or API gateway may be able to offer basic message filtering mechanisms to block this type of request wholesale. However, additional parameters may be necessary for other users and other use cases. It would also require detailed knowledge upfront from development teams on the design and intended use of the API so that operational teams can implement even basic message filters.
API security solutions must be able to identify anomalous API activity where attackers send manipulated API requests with unauthorized parameters. To do this, API security solutions must be able to continuously baseline normal API behavior and identify when additional parameters are passed in API calls that fall outside of typical behavior. API Security solutions should also be able to identify attackers as they probe the API during their reconnaissance phase to gain an understanding of the API structure and business logic.
Salt Security's Michelle McLean speaks with the team at Xolv about how Xolv has deployed Salt to protect the APIs at the heart of its healthcare applications.
As part of our continuing mission here at Salt to educate the broader industry, our technical evangelist, Michael Isbitski, provides a comprehensive overview of the challenges and best practices in API security.