June 25, 2026
PortSwigger : Reflected XSS into Attribute with Angle Brackets HTML-Encoded
In this lab, the website has a reflected XSS vulnerability in the search function.
By danar
2 min read
Lab: Reflected XSS into attribute with angle brackets HTML-encoded This lab contains a reflected cross-site scripting vulnerability in the search blog functionality where angle brackets…
The difference in this lab is that angle brackets like < and > are HTML-encoded. Because of that, a normal payload like:
<script>alert(1)</script><script>alert(1)</script>will not work.
The goal is to inject an attribute and call the alert function.
SOLUTION
First, I accessed the lab and entered a random word in the search box.
Example:
akfgyauiakfgyauiThen I clicked Search.
This step is useful to see how the website handles user input.
After searching the random word, I used Burp Suite to intercept the request.
The request was then sent to Repeater so I could check the response more clearly.
In the response, the random input was reflected inside an HTML attribute.
Example:
<input value="akfgyaui"><input value="akfgyaui">This means the input is placed inside quotation marks in an HTML attribute.
Why I Checked the Response in Burp
I checked the response to know where my input was placed in the HTML page.
This is important because different positions need different payloads.
In this lab, the input is reflected inside a quoted attribute. Also, angle brackets are HTML-encoded, so I cannot inject a new HTML tag using <script> or <img>.
Because of that, the best way is to break out of the attribute value and add a new event handler attribute.
After knowing that the input is inside a quoted attribute, I replaced the random input with this payload:
"onmouseover="alert(1)"onmouseover="alert(1)Then I sent the request or opened the generated URL in the browser.
Why This Payload Works
The payload used is:
"onmouseover="alert(1)"onmouseover="alert(1)The first double quote:
""is used to close the original attribute value.
For example, before injection, the HTML may look like this:
<input value="akfgyaui"><input value="akfgyaui">After the payload is inserted, it becomes similar to this:
<input value="" onmouseover="alert(1)"><input value="" onmouseover="alert(1)">Now, onmouseover becomes a new HTML event attribute.
This part:
onmouseover="alert(1)onmouseover="alert(1)means JavaScript will run when the mouse is moved over the injected element.
The JavaScript code is:
alert(1)alert(1)This shows an alert pop-up with the value 1.
This payload works because the website encodes angle brackets, but it does not properly handle quotation marks inside attributes. So, I cannot inject a new tag, but I can inject a new attribute.
After opening the payload URL in the browser, I moved the mouse over the injected element.
Then, the alert pop-up appeared.
After the alert appeared, the lab status changed to Solved.
This lab shows that XSS can still happen even when angle brackets are encoded.
Because < and > are encoded, I could not use a normal script tag. Instead, I used this payload:
"onmouseover="alert(1)"onmouseover="alert(1)The payload closes the existing attribute value and adds a new event handler. When the mouse moves over the injected element, the browser runs alert(1).
From this lab, I learned that preventing XSS is not only about encoding angle brackets. The application also needs to properly encode quotes and handle user input based on where the input is placed in the HTML.
Thanks for your attention.