Impact & Risk
The defensive impact assessment for XSS: what attackers can do once they have script execution, and how each impact reduces with the right control.
XSS — impact, defensively
EXAMPLE
// SCOPE: defensive learning. Authorised testing only. // ===== Why XSS matters ===== // XSS gives an attacker the privileges of the page's origin in the victim's browser. // Everything that page can read or do, the attacker can read or do. // ===== Direct impacts ===== // 1. Session theft via document.cookie -> takeover the session // 2. Action-on-behalf via fetch / XHR -> POST / DELETE as the victim // 3. Data exfiltration -> read DOM, localStorage, SSO tokens // 4. UI rewriting -> phishing inside the trusted page // 5. Keylogging -> capture passwords / typed text // 6. CSRF amplification -> bypass SameSite if same origin // 7. Pivot to higher-privilege endpoints -> escalate via authenticated API // ===== Controls and what they cut ===== // HttpOnly cookies -> blocks (1) // SameSite + CSRF tokens -> reduces (6) // CSP with nonces -> reduces (2)(3)(4)(5) // Strict origin isolation -> blocks (4)(5) cross-page leakage // Subresource Integrity -> blocks supply-chain XSS via CDN tamper // Trusted Types (CSP) -> blocks raw assignment to dangerous sinks // ===== A defensive demo: minimising damage if XSS happens ===== // Even though you should prevent XSS, defence in depth assumes you missed one. // 1. Cookies the script cannot read: // Set-Cookie: session=abc; HttpOnly; Secure; SameSite=Lax; Path=/ // 2. Strict CSP: // Content-Security-Policy: // default-src 'self'; // script-src 'self' 'nonce-<random>'; // object-src 'none'; base-uri 'self'; frame-ancestors 'none'; // require-trusted-types-for 'script'; trusted-types default; // 3. Trusted Types (modern browsers): // Code that does element.innerHTML = userInput MUST go through a TrustedTypePolicy. // Plain string assignments throw at runtime. // 4. Storage hygiene: // Avoid putting sensitive tokens in localStorage / sessionStorage. // Treat both as exposed if XSS lands. // 5. Origin separation: // Run your dashboard and your user-content viewer on DIFFERENT origins. // XSS in the viewer cannot read dashboard data. // 6. CSP report-only first: // Content-Security-Policy-Report-Only: ...; report-to csp-endpoint // Find injection paths before they become incidents. // ===== Severity tiers (for engagement reports) ===== // Low: output reflected in a context that requires user interaction to fire // Medium: stored XSS on a low-value page (e.g. authenticated-only, no PII) // High: stored XSS on a page that touches authentication / payments / admin // Critical: stored XSS in a privileged context (admin panel, support tool) // ===== Incident response if you find one in prod ===== // 1. Roll the session secret + invalidate active sessions // 2. Sanitise + escape at every render path; deploy fix // 3. Audit logs for likely victims; assess data exposure // 4. Add a regression test that locks in the escape // 5. Communicate per your data breach policy // ===== Patterns to internalise ===== // - Treat XSS as 'fully compromised within the origin' // - HttpOnly + Secure + SameSite stops cookie theft // - Strict CSP + Trusted Types reduces blast radius // - Separate trusted and untrusted content origins // ===== Pitfalls ===== // - 'It is only reflected XSS' -> still high if the victim is an admin // - HttpOnly without Secure -> stolen over HTTP // - CSP with 'unsafe-inline' on script-src -> defeats the safety net // - Storing PII in localStorage thinking it is 'client only'
Why it matters
Once script runs in your origin, everything the page can do is in scope. Layer the controls — HttpOnly cookies, strict CSP, Trusted Types, origin separation, no PII in localStorage — and the blast radius of any leaked XSS shrinks dramatically. That layered floor is what turns a critical into a low.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
// What an XSS payload can do (without leaving your domain): // Steal session cookies (unless HttpOnly). // Make authenticated API calls as the victim. // Show fake login forms (UI phishing). // Pivot to internal services via SSRF-ish behaviour from the browser.Try it Yourself »
Discussion
Loading…