DOM XSS in document.write sink using source location.search inside a select element
Description
The website in this lab contains a DOM-based cross-site scripting vulnerability in the stock checker functionality. It uses the JavaScript document.write
function, which writes data out to the page. The document.write function is called with data from location.search
which you can control using the website URL. The data is enclosed within a select element.
Reproduction and proof of concept
On the product pages, notice that the dangerous JavaScript extracts a storeId parameter from the
location.search
source. It then usesdocument.write
to create a new option in the select element for the stock checker functionality.
<form id="stockCheckForm" action="/product/stock" method="POST">
<input required type="hidden" name="productId" value="4">
<script>
var stores = ["London","Paris","Milan"];
var store = (new URLSearchParams(window.location.search)).get('storeId');
document.write('<select name="storeId">');
if(store) {
document.write('<option selected>'+store+'</option>');
}
for(var i=0;i<stores.length;i++) {
if(stores[i] === store) {
continue;
}
document.write('<option>'+stores[i]+'</option>');
}
document.write('</select>');
</script>
<button type="submit" class="button">Check stock</button>
</form>
Add a
storeId
query parameter to the URL and enter a random alphanumeric string as its value. Request this modified URL.
https://0a07003f04c9eae2c0c9af0b0027005f.web-security-academy.net/product?productId=4&storeId=abcdef
In the browser, the random string is now listed as one of the options in the drop-down list.
Right-click and inspect the drop-down list to confirm that the value of the storeId parameter has been placed inside a select element.
Create a suitable XSS payload inside the
storeId
parameter:
https://0a07003f04c9eae2c0c9af0b0027005f.web-security-academy.net/product?productId=4&storeId=<script>alert(0)</script>