Stored XSS into anchor href attribute with double quotes HTML-encoded

4 min read Easy PortSwigger
XSS
Contents

On this page

The lab

Here is how PortSwigger describes it

This lab contains a stored cross-site scripting vulnerability in the comment functionality. To solve this lab, submit a comment that calls the alert function when the comment author name is clicked.

Stored XSS, and an href that runs code#

Stored XSS is the patient cousin of the reflected kind. Instead of bouncing our input back on one request, the site keeps it, tucks it into a database, and serves it to every visitor who loads the page from then on. That is what makes stored bugs serious in nature we do not need to trick anyone into following a crafted link, we just leave the payload sitting there and let the page hand it out

the sink this time is one we have met before, the href of a link. link does not only take you places. if its address starts with javascript: the browser runs the rest as code the moment the link is clicked. so if we get to decide what an href holds we can make a perfectly normal looking link run our Javascript on click

Step 1 - poking the comment box#

description tells us the bug lives in the comment functionality, so there is no need to wander around the home page. open any post, scroll down, and there is the comment form

first thing to do is learn how the app treats what we type, so send a comment with a mix of the characters that usually matter

Logicbreaker "'<xx>
22

When it renders back, those characters come out encoded rather than live, so the comment body itself is a dead end. Nothing we put in the text is going to break out and run. but one detail on the page is worth a second look

comment shows its author name as a link, and that link points at the website the commenter gave when posting. in the page source it looks like this.

html
<a id="author" href="https://logicbreaker.sh">Logicbreaker</a>

that href is filled straight from the website field of the comment form, which means we control it. And we already know an href will happily run a javascript: address when clicked. this is the same idea as the jQuery anchor href lab from earlier, so the methodology carries straight over.

Two things are new here though, and both matter. The first is that this is stored, not built in the browser from the URL like that earlier lab was. Our value is saved on the server and stamped into the link for every visitor, so the payload reaches the victim on its own with no crafted link to send them.

Step 3 - dropping the payload and solving#

so in the website field of the comment, instead of a real address, we put this.

javascript:alert(1)
222

Post the comment. The author name now renders as a link whose href is our payload.

html
<a id="author" href="javascript:alert(1)">Logicbreaker</a>

the browser sees the javascript: scheme, runs alert(1), and the popup fires. Because the comment is stored, the very same thing happens for anyone who clicks that author name later.

With this, the lab is solved!