API6:2019 — Mass Assignment II
In our lab walkthrough series, we go through selected lab exercises on our AttackDefense Platform. Premium labs require a subscription, but you can sign in for free to try our community labs and view the list of topics — no subscription or VPN required!
Hello all, today we will be looking into OWASP API Security Top 10’s another vulnerability, i.e. Mass Assignment
The Issue:
“The API takes data that a client provides and stores it without proper filtering for whitelisted properties. Attackers can try to guess object properties or provide additional object properties in their requests, read the documentation, or check out API endpoints for clues where to find the openings to modify properties they are not supposed to on the data objects stored in the backend.”
Reference: https://apisecurity.io/encyclopedia/content/owasp/api6-mass-assignment.htm
Lab Scenario
We have set up the below scenario in our Attack-Defense labs for our students to practice. The screenshots have been taken from our online lab environment.
Lab: Mass Assignment II
This lab environment consists of a Banking WebApp. The webapp allows the users to update their password and email id after a successful login. The issue is that for one of the update requests, the API uses the data provided by the user and performs a mass object assignment instead of assigning only the required attributes.
Note: The authorization system relies on a scope parameter in the issued token. If the token issued to a user has the scope of “account-write”, then they get write access on the account, else, for token having the scope of “account-read”, the user gets read-only access to the account.
Challenge Statement
Objective: Leverage the vulnerability to increase your account balance and retrieve the Golden Ticket from the Bank API!
Solution
Step 1: Check the IP address of the machine.
Command: ifconfig
The IP address of the machine is “192.248.164.2”
Therefore, the Banking WebApp is running on “192.248.164.3”, at port 5000.
Step 2: Viewing the Banking WebApp.
Open the following URL in firefox.
URL: http://192.248.164.3:5000
Step 3: Configuring the browser to use BurpSuite proxy and making BurpSuite intercept all the requests made to the API.
Launch BurpSuite.
Select Web Application Analysis > burpsuite
The following window will appear:
Click Next.
Finally, click Start Burp in the following window:
The following window will appear after BurpSuite has started:
Configure the browser to use the Burp proxy listener as its HTTP Proxy server.
Open the browser preference settings and search for network proxy settings.
Select Manual Proxy Configuration and set the HTTP Proxy address to localhost and the port to 8080.
Click OK.
Everything required to intercept the requests has been setup.
Step 4: Interacting with the Banking API using the WebApp.
Login into the webapp using the provided credentials:
Username: elliot
Password: elliotalderson
Note: Make sure that intercept is on in BurpSuite
Notice the corresponding requests in BurpSuite.
Forward the above request.
Forward the above request and view the changes reflected in the web app.
Click on Check Balance button.
Forward above request.
Click on the Get Golden Ticket button.
Forward the above request.
Notice that a JWT Token is sent in the request.
JWT Token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJEdW1teSBCYW5rIiwiYWNjdCI6MTMzNywic2NvcGUiOiJhY2NvdW50LXJlYWQiLCJleHAiOjE1NzU4ODcwODgsImlhdCI6MTU3NTg4NjQ4OH0.iMbfch1vv3DvNiWBmpBWace-YosFJba6la-X5hJFfzno6eWSggOC8AMryRlF8AtrAS7ykMgcsLjsRuX22MqovbrbUMjnkVQ8Ron_sJu2JyHKRh62H7uSXt54s-cx6lAFLGlvUxjfhTqo2cSaNXBsSqcRhi4oiiseHRFX5b342nD9pXL-9RaRv7JxJkIgdgUzEtCOnq4U5-cAOzEHKoksBh2EiLzV08J2bS8HZ3YL9gaZZCqWl9y-JDYHWffNv8ljz57nr1KSlpb7xN5bLKhyKQpMJ85Csf2R3ePybE-fcVquXyLVr4myz2_dOiNR0Jpwr47nW2aGNFTi32A6YxQYmw
Visit https://jwt.io and decode the above-obtained token:
Notice that the token has a scope claim and it is set to the value “account-read”.
Forward the above request and view the changes reflected on the web page.
As mentioned in the challenge description:
“The authorization system used relies on a scope parameter in the issued token. If the token issued to a user has the scope of “account-write”, then they get write access on the account, else, for scope of “account-read”, the user gets read-only access to the account.”
And the token obtained above has scope set to “account-read”.
This means that the above user (“Elliot Alderson”) also has read-only access to the account. Therefore, he can only read his account balance.
Step 5: Resetting password for Elliot.
Set the password to 123.
Forward the above request.
Forward the above request.
Notice that the password got successfully updated.
Check the response in the HTTP History window in Burp Proxy.
Notice that the response does not reflect anything about the attributes for a user.
Step 6: Checking the documentation for Banking API.
Check the Updating Password paragraph under the Updating Details section.
As it is mentioned in the “Updating Password” paragraph:
“Password update is done by assigning the available JSON attributes in the user supplied data to the available attributes in the user schema.”
That means the mass assignment issue could be leveraged in this case.
But the customer attributes are also unknown.
Navigate back to the main page of the API documentation.
Check the Customer Attributes under the Schema Section.
Notice that there is an attribute called “is_admin_account” that indicates whether the account is of admin user or not.
Step 7: Making Elliot the admin user.
Resetting the password for Elliot again:
Check the corresponding request in BurpSuite.
Forward the above request.
Check the changes reflected on the web page.
Click on the Update Profile button.
Set the new password as 1234.
Check the corresponding request in BurpSuite:
Forward the above request.
Send the above request to Repeater and turn off the intercept mode:
Notice on the web page a pop-up gets displayed acknowledging that the password has been updated successfully.
Navigate to the Repeater window and send a request again after editing the data sent:
Add the “is_admin_account” field in the JSON that is sent and set its value to “true”.
Send the modified request.
Notice the response. It reflects that password has been successfully updated.
Login to the web app again using the updated credentials:
Click on Check Balance button.
Note: Run the Burp Proxy in intercept mode for this request to get the JWT token passed in the request.
Notice that a JWT Token is passed in this request.
JWT Token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJEdW1teSBCYW5rIiwiYWNjdCI6MTMzNywic2NvcGUiOiJhY2NvdW50LXdyaXRlIiwiZXhwIjoxNTc2MDAxMDM4LCJpYXQiOjE1NzYwMDA0Mzh9.O6cRuKSlkM0lLunS2mrC3XWxDsHJaeFXArZmo68p9aE8jY7vcryLwNXQXMRXIpC5hnpZdvKtMd21yXc-9yuExN2bTxV_FprdO8nOjV4P4d2btHgRJpqIXSj9MusRMBogJmPurWkpZVMJ6Tclt-_j5-gVbDe6_sTLGfBfYzILllyx9GSFGkHwzM1NwQgA-d4B6H5ZF22RQ96xK0E21-KXU09NwtGxLWhsxoZr0rzX-da1k-CK1ZpLptHWVQG7yFAW7VlceXIzmqfPvxO7bTNip_eDXvmMkjXAvyxdlTKffr02u51yA-zRA6jMdt6t7IeYJoU6v5schUJJiCREZQ5xjw
Decoding this token using https://jwt.io:
Notice that this token has a scope of “account-write”.
Step 8: Increasing the balance for Elliot’s account and retrieving the Golden Ticket.
In the challenge description, it is mentioned that the /balance endpoint supports a POST request as well. That request is used to modify the account balance.
Send a POST request to the /balance endpoint and modify the balance of elliot’s account and set it to a value greater than 5000000:
Command: curl -X POST -H “Content-Type: application/json” http://192.248.164.3:8081/balance -d ‘{“acct”: 1337, “balance”: 100000000, “token”: “eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJEdW1teSBCYW5rIiwiYWNjdCI6MTMzNywic2NvcGUiOiJhY2NvdW50LXdyaXRlIiwiZXhwIjoxNTc2MDAxMDM4LCJpYXQiOjE1NzYwMDA0Mzh9.O6cRuKSlkM0lLunS2mrC3XWxDsHJaeFXArZmo68p9aE8jY7vcryLwNXQXMRXIpC5hnpZdvKtMd21yXc-9yuExN2bTxV_FprdO8nOjV4P4d2btHgRJpqIXSj9MusRMBogJmPurWkpZVMJ6Tclt-_j5-gVbDe6_sTLGfBfYzILllyx9GSFGkHwzM1NwQgA-d4B6H5ZF22RQ96xK0E21-KXU09NwtGxLWhsxoZr0rzX-da1k-CK1ZpLptHWVQG7yFAW7VlceXIzmqfPvxO7bTNip_eDXvmMkjXAvyxdlTKffr02u51yA-zRA6jMdt6t7IeYJoU6v5schUJJiCREZQ5xjw”}’
Notice the account balance now:
Note: Turn off the intercept mode in Burp Proxy for all further requests.
The balance was updated successfully.
Since the balance is now greater than $5000000, the Golden Ticket could be retrieved.
Golden Ticket: This_Is_The_Golden_Ticket_2d604133aa55938aca1e14dfbd0fe9e5
It was great! But tell me how to avoid the issue in the first place?
The issue was that the request parameters were assigned to the internal objects.
Therefore, the few possibilities to overcome this issue would be:
- To avoid binding incoming request data to the internal objects and only assigning the expected attributes depending on the request.
- The properties that are not to be modified should be marked as read-only in the object schema to avoid overwriting those while performing mass assignment.
Stay Safe and Happy Hacking!
References:
Go beyond walkthroughs with hands-on practice. Subscribe now and gain access to 2000+ lab exercises including this one! We also provide on-demand bootcamps — follow along with instructors as they go through the labs and progressively master in-demand topics regardless of time zone!