PortSwigger's "DOM XSS in jQuery anchor href attribute sink using location.search source" Walkthrough
This is the third of the three Apprentice-level DOM-based XSS Labs from Portswigger. Before we get started, you’ll need a Portswigger Academy account. This blog post shows how to solve the lab manually.
After logging in, head over to the lab, located at https://portswigger.net/web-security/cross-site-scripting/dom-based/lab-jquery-href-attribute-sink
. You can find this through the Academy learning path list, or linked within the DOM-based XSS blog post.
Challenge Information
Click the “Access the Lab” button and you will be taken to a temporary website that is created for your account. This will be in format https://<random string here>.web-security-academy.net/
.
This is a DOM-based XSS attack. This means that our malicious input will be passed to a “sink” that supports dynamic code execution through a Javascript, JQuery, etc. function call.
The website looks like this:
There’s a feedback form but if we fill it out, it doesn’t really do anything.
One interesting thing that caught my eye was the URL on the feedback page:
https://<random-string>.web-security-academy.net/feedback?returnPath=/
The returnPath
value likely corresponds to the Back
link. Let’s try it out.
Changing the return path
If we change the returnPath
value from /
(to return to the home page) to another value:
https://<random-string>.web-security-academy.net/feedback?returnPath=hi
Then view the <Back
HTML in Dev Tools, we see this:
Our value of “hi” is inserted into the href
attribute.
This is because of the script, shown in the same screenshot, which uses jQuery to get a handle on the <a>
element (via its id, backLink
), then assigns the value of the window.location.search
‘s returnPath
variable (“hi”) to the href
attribute.
Let’s see what happens if we add a "
to our input, then add another attribute to the <a>
tag.
https://<random-string>.web-security-academy.net/feedback?returnPath=hi" onload="alert(1)
While this appears to work in HTML, hovering over the link on the page reveals that the entire input is being interpreted as the href
value.
Lab Solution
It turns out I was overcomplicating this one, as the alert()
needs to happen on a click, rather than being automatically triggered.
All we need to do, then, is to pass a javascript
call into the href
attribute. We can do this with javascript:alert(document.cookie)
as our payload:
https://<random-string>.web-security-academy.net/feedback?returnPath=javascript:alert(document.cookie)
Check that the HTML (viewed in Dev Tools‘ Elements tab) looks like this:
Then click the <Back
button to trigger the attack: