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: