Reflected XSS
The most common XSS variant. A search box, an error page, a URL parameter — any input echoed back without escaping becomes a script execution point.
The most common XSS variant. A search box, an error page, a URL parameter — any input echoed back without escaping becomes a script execution point.
Reflected XSS is the most common subtype of cross-site scripting. Unlike stored XSS, the payload does not persist on the server — it is reflected off the server in the immediate response. The attacker must trick the victim into sending a crafted request, typically through a phishing link.
Reflected XSS occurs when an application accepts user input and echoes it back in the HTTP response without proper escaping. The most common reflection points are search result pages, error messages, and form validation feedback. The attacker crafts a URL containing the payload and lures the victim into clicking it — the server reflects the payload, the browser executes it.
Because the payload is part of the URL, the attack surface extends beyond the web application itself. Shortened URLs, QR codes, and redirect chains can all hide the malicious query string. Security scanners and firewall logs often catch reflected XSS because the payload appears in server access logs — but that only helps after the fact.
Type a query into the search field below. The page reflects your query in the URL and renders it in the results area. Try a payload like <img src=x onerror=alert(1)>. Toggle safe mode to see how HTML escaping prevents execution.
<!-- VULNERABLE — raw reflection -->
<p>You searched for:
(empty)
</p>In September 2010, a reflected XSS vulnerability was discovered in Twitter's search and trending topics feature. An attacker could craft a tweet containing an onmouseover event handler. When a victim hovered over the tweet, the handler executed JavaScript that retweeted the payload to all of the victim's followers. The worm spread rapidly because hovering over any infected tweet — even accidentally — triggered the propagation. Twitter had to temporarily disable the affected feature while a fix was deployed.
This incident demonstrates how reflected XSS can self-propagate through a social network even without stored persistence. The payload was in the URL, not the database, but the worm spread faster than Twitter could filter it. More recently, the British Airways 2018 data breach affecting 380,000 payment records was traced back to a third-party script loaded via an XSS-vulnerable integration.
// VULNERABLE — reflects query string unescaped
app.get('/search', (req, res) => {
res.send('<p>Results for: ' + req.query.q + '</p>');
});
// SAFE — escape HTML before reflection
app.get('/search', (req, res) => {
const q = escapeHtml(req.query.q ?? '');
res.send('<p>Results for: ' + q + '</p>');
});
// SAFE — Content Security Policy as defence-in-depth
res.setHeader('Content-Security-Policy',
"default-src 'self'; script-src 'self'");The primary defence against reflected XSS is context-aware HTML escaping on every value that originates from user input — query parameters, form fields, headers, and URL fragments. Server-side template engines like React JSX, Jinja2, and Handlebars escape HTML by default, but raw string concatenation bypasses that protection entirely.
A Content Security Policy with a strict script-src directive acts as a safety net. Even if escaping fails, the browser will refuse to execute inline scripts. Combined with input validation that rejects obvious HTML patterns, these layers make reflected XSS significantly harder to exploit.
1.What distinguishes reflected XSS from stored XSS?
2.Which of the following is a typical reflection point for reflected XSS?
3.How did the 2010 Twitter onmouseover worm propagate?