PortSwigger's "Reflected XSS into attribute with angle brackets HTML-encoded" Walkthrough

This is another of the Reflected XSS Labs from Portswigger. Before we get started, you’ll need a Portswigger Academy account. This level is completed without Burp Suite, but we have a blog post to help you set it up for future levels.

After logging in, head over to the lab, located at https://portswigger.net/web-security/cross-site-scripting/contexts/lab-attribute-angle-brackets-html-encoded. You can find this through the Academy learning path list, or linked within the Reflected 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 reflected XSS attack. This means that our malicious input (in the form of some script that executes) will be reflected onto the page, rather than stored in a database or somewhere else more permanent.

Our input will have the bracket characters (< and >) HTML encoded, meaning we will have to find a different attack vector from last time.

If we open up the website, we see that it’s once again a blog with a search bar at the top:

If we enter something into the search bar, it is added to the URL as a query parameter, as shown at the top of this image:

This is previously where we injected our <script>alert('hi')</script> payload. If we try that again, we see that our input is HTML encoded and displayed as text, rather than interpreted as part of the HTML (and thus, executed):

If we take a look at the HTML using Dev Tools, we see this:

Our input was interpreted as text within the <h1> tags.

A New Approach

Our original approach doesn’t work, and the lab instructions tell us that we need to “perform a cross-site scripting attack that injects an attribute.”

A Google search finds this resource, which has a section on “Inside HTML tags attribute“:

The second item in the list describes our scenario: > is encoded.

But we can still inject an attribute that will autofocus on the element, and then call an alert when the element is in focus (so, immediately).

We can use their payload: " autofocus onfocus=alert(1) x=" (or update it to say hi: " autofocus onfocus=alert('hi') x=")

Lab Solution

Copy paste this payload (" autofocus onfocus=alert(1) x=") into the search bar, and it should pop up an alert:

Here’s the resulting HTML:

This payload will trigger an alert when the relevant element is in focus. The onfocus event typically relates to input, select, and a elements.

If you remove the autofocus portion of the payload, you will have to focus the correct element on your own by hovering your cursor over different parts of the page. It turns out that the search bar input is what the onfocus is acting on.