Reflected XSS into attribute with angle brackets HTML-encoded
🧠 Reflected XSS into Attribute with Angle Brackets HTML-Encoded
Reflected Cross-Site Scripting (XSS) remains one of the most common web vulnerabilities, especially when user input is embedded into HTML without proper context-aware encoding. This lab demonstrates a nuanced case where input is reflected into an HTML attribute, and although angle brackets are encoded, the application is still vulnerable due to improper handling of quotation marks and event attributes.
The application reflects user input in two places. The first reflection point is inside an <input> element’s value attribute:
<input type="text" placeholder="Search the blog..." name="search" value="ATTACKER_INPUT">
The second reflection appears in the page header:
<h1>0 search results for 'ATTACKER_INPUT'</h1>
At first glance, the presence of HTML encoding for angle brackets (< and >) may give the impression that the application is secure. However, this protection only addresses one specific injection vector HTML tag injection and does not account for attribute context injection, which is the real issue in this case.
The critical vulnerability lies in the first reflection point, where user input is embedded inside a double-quoted HTML attribute. In this context, the browser interprets everything between the quotes as part of the attribute value. If an attacker can break out of this quoted context, they can inject new attributes, including event handlers that execute JavaScript.
This is exactly what the successful payload achieves:
/?search="onmouseup%3D"alert%281%29"
When URL-decoded, the payload becomes:
"onmouseup="alert(1)"
This effectively transforms the original HTML into something like:
<input type="text" value="" onmouseup="alert(1)">Lab example from Portswigger:
Here’s what happens step by step. First, the injected double quote (") closes the original value attribute. Next, the attacker introduces a new attribute, onmouseup, which is a valid HTML event handler. Finally, the JavaScript payload (alert(1)) is assigned to this event. When the user moves their mouse over or interacts with the input field, the event is triggered and the JavaScript executes.
What makes this vulnerability particularly interesting is that it bypasses the application’s attempt to sanitize input by encoding angle brackets. Since no <script> tags or HTML elements are needed, the encoding of < and > becomes irrelevant. The attack operates entirely within the attribute context, leveraging the browser’s parsing behavior rather than injecting new tags.
The second reflection point inside the <h1> element is not directly exploitable in the same way because it is rendered in a text context. Even if angle brackets were not encoded, injecting executable code there would typically require breaking out into HTML, which is prevented by encoding. This highlights an important principle in XSS: the exploitability of input depends heavily on the context in which it is rendered.
The root cause of this vulnerability is improper output encoding. While the application attempts to sanitize input, it does not apply the correct encoding strategy for the attribute context. In HTML, different contexts require different encoding rules. For attributes, special characters such as quotes (" and ') must be properly escaped to prevent breaking out of the attribute value. Failing to encode these characters allows attackers to inject new attributes or modify existing ones.
To prevent this type of vulnerability, developers must use context-aware encoding. When inserting user input into HTML attributes, both angle brackets and quotation marks should be encoded. For example, double quotes should be converted to ", ensuring that they cannot terminate the attribute prematurely. Alternatively, developers can use templating frameworks or libraries that automatically handle safe rendering of user input.
Another effective mitigation strategy is to avoid directly embedding untrusted input into HTML whenever possible. Instead, safer APIs such as setting element properties via JavaScript (e.g., element.value = userInput) can reduce the risk, as they do not involve parsing raw HTML strings. Additionally, implementing a strong Content Security Policy (CSP) can provide an extra layer of defense by restricting the execution of inline scripts.
In conclusion, this lab demonstrates that encoding angle brackets alone is not sufficient to prevent XSS. Attackers can exploit other contexts, such as HTML attributes, by manipulating how the browser parses input. Understanding these nuances is essential for both identifying vulnerabilities and implementing effective defenses.
.webp)

.webp)
Comments