Reflected XSS - Attribute Injection Demonstration
Angle Brackets HTML-Encoded - Break Out of Attribute
< > are HTML-encoded,
so you cannot inject new HTML tags. Instead, you must break out of the attribute
and inject an event handler.alert(1) using an event handler like onmouseover.
(none)
< > are encoded, so <script> won't work" and add an event handler"onmouseover="alert(1)onfocus, onclick, onloadThe application takes user input and places it directly inside an HTML attribute value. While angle brackets are encoded (preventing new tag injection), quotes are not escaped, allowing you to break out of the attribute and inject event handlers.
"onmouseover="alert(1) — Hover mouse over search box"onfocus="alert(1)"autofocus=" — Auto-triggers when page loads"onclick="alert(1) — Click the search box"onload="alert(1) — Fires on element load<!-- User input reflected inside attribute --> <input type="text" value="USER_INPUT_HERE"> <!-- With payload: "onmouseover="alert(1) --> <input type="text" value=""onmouseover="alert(1)"> <!-- Browser interprets as: --> <input type="text" value="" onmouseover="alert(1)"> <!-- ^^^^ New event handler! ^^^^ -->
// FIX 1: HTML Entity Encode ALL special characters
function escapeAttribute(unsafe) {
return unsafe
.replace(/&/g, '&')
.replace(/"/g, '"') // Encode double quotes
.replace(/'/g, ''') // Encode single quotes
.replace(//g, '>');
}
// Server-side (PHP example)
$safe_value = htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
echo '<input type="text" value="' . $safe_value . '">';
// FIX 2: Use template engines with auto-escaping
// React: <input value={userInput} /> (auto-escapes)
// Vue: <input :value="userInput" /> (auto-escapes)
onmouseover — Mouse hovers elementonfocus — Element receives focusonclick — Element clickedonload — Element finishes loadingonerror — Error occurs on elementonscroll — Element is scrolledoninput — User types in inputThis lab runs entirely in your browser — safe for educational purposes.