Difficulty: Apprentice
Vulnerability: DOM-based Cross-Site Scripting (XSS) via innerHTML
Lab Link: https://portswigger.net/web-security/cross-site-scripting/dom-based/lab-innerhtml-sink
The objective of this lab was to exploit a DOM XSS vulnerability in the search blog functionality.
My goal was to inject a payload into the innerHTML sink that triggers
the alert() function.
Upon starting the lab, we see a blog web application which has a search functionality, differnt blog posts on the web application. As the lab hinted that the source of the input was location.search, which is used for getting the input from the URL, I started off with the search functionality presnt in the web application.
For testing purpose, I started with capturing the search request made by the web application using Burp suite and inside the repeater tab to continue to try & experiment with finding the vulnerability, if it exists. On careful investigation, I found a JavaScript function in the server’s response which was vulnerable.
The function implements innerHTML which is a dangerous function
and could be used to write dangerous function into the HTML code which
could do harmful things.
For exploiting the vulnerability which exists in the web application, we can break it into two steps, step one implements passing the payload to the source which accepts input from user controlled source. Step two is the indirect step where the sink accepts the input from the source and if vulnerable, which in this case it is, executes the dangerous function.
Step 1: The source
var query = (new URLSearchParams(window.location.search)).get('search');
In this above piece of code which is the source, it accepts the
input from the URL, especially from the search parameter’s value,
since there was no other validation checks implemented by the developers,
we can go with a simple payload like
Step 2: The sink
function doSearchQuery(query) {
document.getElementById('searchMessage').innerHTML = query;
}
This is the sink in the web application, which is going to pass our
user controller input via the query variable and executes the
dangerous function