Skip to content

CWE-80: XSS (Basic)

Overview

This guidance helps you interpret and remediate findings from DAST (Dynamic Application Security Testing) tools. The scanner detected that the application reflected user input containing basic XSS vectors (HTML tags with executable content) into web pages without proper neutralization, allowing script execution in victims' browsers. DAST tools identify this by:

Detection Methods:

  • Script Tag Injection: Submitting <script>alert(1)</script>, <script>alert(document.domain)</script>
  • Event Handler Injection: Testing <img src=x onerror=alert(1)>, <body onload=alert(1)>, <svg onload=alert(1)>
  • Iframe/Object Injection: Injecting <iframe src=javascript:alert(1)>, <object data=javascript:alert(1)>
  • Callback Detection: Using scanner-specific payloads that trigger HTTP requests to scanner infrastructure when executed
  • DOM Inspection: Automated browser testing to verify actual script execution in rendered page
  • Response Analysis: Searching for verbatim reflection of payloads in HTML context without encoding

HTTP Evidence:

  • Scanner payloads appearing unescaped in HTML response bodies (<script>alert(ZAP)</script> in view-source:)
  • HTTP callbacks to scanner infrastructure (Burp Collaborator: <script src=https://burpcollaborator.net/xss></script>)
  • Reflected input within HTML tags without HTML entity encoding (< not converted to &lt;)
  • Response headers lacking XSS protection (missing or disabled X-XSS-Protection, weak CSP)
  • JavaScript execution observable through automated browser instrumentation (Selenium, Playwright)
  • Variation in response when dangerous characters (<, >, ", ') are submitted vs. safe characters

Scanner Behavior: OWASP ZAP (XSS Reflected, Persistent rules 40012-40017) and PortSwigger Burp Scanner inject polyglot XSS payloads, context-specific vectors, and callback-based probes. Modern scanners use headless browsers to verify actual JavaScript execution, not just payload reflection. They test reflected (non-persistent) and stored (persistent) XSS across all input vectors including URL parameters, POST bodies, headers (User-Agent, Referer), and JSON/XML data.

Analyzing the Dynamic Scan Result

What the DAST Scanner Found

When reviewing your security scan results, you'll see:

HTTP Request Details

  • URL and endpoint that triggered the finding
  • HTTP method (GET, POST, etc.)
  • Query parameters or form data with test payloads
  • Request headers and body content

HTTP Response Evidence

  • Response showing the vulnerability manifestation
  • Evidence of improper handling or injection
  • Runtime behavior indicators

Attack Vector

  • Which parameter or input is vulnerable
  • Type of exploitation possible
  • Context where the vulnerability appears

Mapping DAST Findings to Source Code

Find the Vulnerable Endpoint

Use the HTTP request URL to locate the code:

# Search for output/rendering code
grep -r "render" src/
grep -r "innerHTML" src/
grep -r "echo" src/
grep -r "print" src/

Locate Output Generation

Common patterns to search for:

  • Reflected XSS: URL parameters echoed in response
  • Stored XSS: Database content rendered without escaping
  • DOM XSS: JavaScript manipulating DOM with user input
  • Template rendering: Unsafe variable interpolation

Find Unescaped Output

Search for rendering code:

# Find output operations
grep -r "innerHTML.*param" src/
grep -r "echo.*GET" src/
grep -r "safe.*False" src/
grep -r "dangerouslySetInnerHTML" src/

Trace to Vulnerable Operation

Look for XSS vulnerabilities:

  • Reflected XSS: ?search=<script>alert(1)</script> echoed
  • Stored XSS: Comment field stored and rendered unescaped
  • DOM XSS: innerHTML = location.hash
  • Template XSS: {{ user_input | safe }} in Jinja
  • JavaScript context: User input in <script> tags

Remediation

Core principle: Never include untrusted input in HTML output without context-appropriate output encoding so it cannot be interpreted as executable markup or script.

→ For comprehensive remediation guidance, see Static CWE-80 Guidance

Language-Specific Guidance

The static guidance provides detailed remediation steps for many languages. If you need language-specific examples:

Verification and Follow-Up Testing

After applying the fix:

Reproduce the Vulnerability

# Test reflected XSS
curl "http://localhost/search?q=<script>alert(1)</script>"
curl "http://localhost/user?name=<img src=x onerror=alert(1)>"

# Check if payload is reflected unescaped

Verify the Fix

  • Confirm all user input HTML-escaped
  • Verify output encoding at the sink; input validation alone is insufficient for XSS.
  • Verify Content-Security-Policy is present as defense-in-depth, not as a replacement for output encoding.
  • Check template auto-escaping enabled
  • Ensure JavaScript context properly escaped
  • Test that XSS payloads are neutralized

Test Edge Cases

# Basic payloads
<script>alert(1)</script>
<img src=x onerror=alert(1)>
<svg/onload=alert(1)>
# Event handlers
<body onload=alert(1)>
<input autofocus onfocus=alert(1)>
// JavaScript context
'; alert(1)//
"); alert(1)//

// Filter bypasses
<scr<script>ipt>alert(1)</scr</script>ipt>
<img src="x" onerror="alert(1)">

// Or use browser DevTools Network tab to copy as cURL

Re-run DAST Scanner

Run your dynamic scanner again on the fixed endpoint to confirm remediation.

Additional Resources