Portswigger Academy — Stored XSS into onclick event with angle brackets and double quotes HTML-encoded and single quotes and backslash escaped — Write-up

In this write-up I will be showing my thought process behind solving the aforementioned Portswigger Academy challenge. DISCLAIMER! This write-up contains the answer to the challenge, so if you are here for hints, watch out:)

In the challenge description we get a clear understanding of what our attack vector for this challenge is, and in the Portswigger Academy article we also get a good hint for what we need to do to solve this lab.

The article talks about how because of the browsers behavior, i.e. it first parses HTML tags and attributes, then decodes any HTML inside the attributes before they are evaluated further, we can use HTML-encoding to bypass some filters. Like in this challenge, single quotes and backslashes get escaped, meaning we cannot supply our own backslash to make our single quote useful.

When I first supplied "test.com" as a string in the website parameter in the comment form, the DOM looked like this:

<a id="author" href="https://test.com" onclick="var tracker={track(){}};tracker.track('https://test.com');">testing</a>

Therefore, I encoded the single quote on this website, and got "'" as a result. When I then used the encoded version of the single quote as input, making my input look like this "test.com'", we can see how this was interpreted by the browser in the DOM:

<a id="author" href="https://test.com'" onclick="var tracker={track(){}};tracker.track('https://test.com'');">testing</a>

It gets interpreted and decoded! Meaning we have broken out of the string inside the ".tracker(…)" function. Now all we need to make our alert pop up and solve this lab is: Close the parentheses and add a semi-colon, add "alert(1);", and comment out the trailing characters so that they don't mess with our alert. Taking all of this into consideration, this is what the final input that solved the lab looked like:

" https://test.com');alert(1);// "

Putting this into the website parameter in the comment form, made the DOM look like this :

<a id="author" href="https://test.com');alert(1);//" onclick="var tracker={track(){}};tracker.track('https://test.com');alert(1);//');">testing</a>

Thank you for taking the time to read this write-up! This is one of my first stories here on Medium, although maybe some time has passed and you are reading this at a later date, but do make sure to check out the few others that I have posted.