API6:2019 — Mass Assignment II

Shivam Bathla
Pentester Academy Blog
10 min readJul 29, 2020

--

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

Determining the IP address of the host machine

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

Viewing the Banking webapp

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

Launching BurpSuite

The following window will appear:

Launching BurpSuite (contd.)

Click Next.

Finally, click Start Burp in the following window:

Launching BurpSuite (contd.)

The following window will appear after BurpSuite has started:

Launching BurpSuite (contd.)

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.

Changing browser settings to proxy all http requests through BurpSuite

Select Manual Proxy Configuration and set the HTTP Proxy address to localhost and the port to 8080.

Changing browser settings to proxy all http requests through BurpSuite (contd.)

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

Login using the provided credentials

Notice the corresponding requests in BurpSuite.

Forward the OPTIONS request to the /login endpoint

Forward the above request.

Forward the login request

Forward the above request and view the changes reflected in the web app.

The login was successful!!

Click on Check Balance button.

Request to check the account balance

Forward above request.

The balance of the user after the request was above forwarded

Click on the Get Golden Ticket button.

Retrieving the Golden Ticket

Forward the above request.

Retrieving the Golden Ticket (contd). Notice the JWT Token sent in the 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:

Decoding the above obtained JWT 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.

The Golden Ticket couldn’t be retrieved due to insufficient balance

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.

Click on the update profile button

Set the password to 123.

Set the new password to “123”
Notice the request to update the password

Forward the above request.

Notice the request to update the password (contd.)

Forward the above request.

The password was successfully changed!!

Notice that the password got successfully updated.

Check the response in the HTTP History window in Burp Proxy.

Notice the response of the above request in the HTTP History window

Notice that the response does not reflect anything about the attributes for a user.

Step 6: Checking the documentation for Banking API.

Checking the Banking API Documentation
Checking the Introduction section

Check the Updating Password paragraph under the Updating Details section.

Reading about updating password

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.

Checking the Schema secuton

Check the Customer Attributes under the Schema Section.

Check out the Customer Attributes

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:

Login again as elliot

Check the corresponding request in BurpSuite.

Forward the login request

Forward the above request.

Forward the login request (contd.)

Check the changes reflected on the web page.

Login was successful

Click on the Update Profile button.

Update the password again

Set the new password as 1234.

Set the new password to “1234”

Check the corresponding request in BurpSuite:

Forward the above OPTIONS request

Forward the above request.

Send the above POST request to repeater

Send the above request to Repeater and turn off the intercept mode:

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:

Navigate to the repeater window

Add the “is_admin_account” field in the JSON that is sent and set its value to “true”.

Add the field is_admin_account with the value “true” to the JSON payload

Send the modified request.

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:

Login using the updated credentials
Login was successful

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.

Request to check the balance. Notice the JWT token in the above 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:

Decoding the above obtained JWT Token

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”}’

Increasing the account balance of elliot’s account

Notice the account balance now:

Check the updated balance

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.

Awesome! We have got the Golden Ticket :)

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:

  1. To avoid binding incoming request data to the internal objects and only assigning the expected attributes depending on the request.
  2. 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:

  1. API6:2019 — Mass Assignment
  2. OWASP API Security
  3. JWT debugger

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!

--

--