iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Intro

Cross-Site Scripting (XSS) is when attacker-controlled data is parsed as code by the browser. Three classes: reflected, stored, DOM-based. Defensively framed.

XSS — what it is

EXAMPLE
// SCOPE: defensive learning on the bundled lab app. Authorised testing only.
// Do not test against systems you do not own or have written permission to test.

// ===== The mechanism =====
// User input ends up in a context (HTML, JS, attribute, URL) where the browser
// PARSES it. Instead of being treated as data, it becomes code.

// ===== The three classes =====
// 1. Reflected:  payload in the request is reflected into the response (search pages)
// 2. Stored:     payload persisted (DB / file) and served later to others (comments)
// 3. DOM-based:  client JS reads untrusted input (location, postMessage) and writes to DOM

// ===== Default-escape (the most important defence) =====
// Modern templates auto-escape by default:
//   Blade {{ value }}              escapes HTML
//   React {value}                  escapes HTML in text children
//   Vue {{ value }}                escapes HTML
//   Handlebars {{value}}           escapes; {{{value}}} does NOT
// Every framework has an OPT-OUT (raw HTML); review every use.

// ===== A safe pattern =====
// User-supplied comment rendered in HTML:
//   server: htmlspecialchars($value, ENT_QUOTES | ENT_HTML5)
//   client: textContent = value     // never innerHTML
// Need rich text? Sanitise with an allowlist (DOMPurify, sanitize-html).

// ===== Content Security Policy =====
// The safety net even when escaping fails.
// Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-<rand>';
// Inline scripts must carry the nonce; everything else is rejected.

// ===== Cookies =====
// HttpOnly + Secure + SameSite=Lax (or Strict) — even if XSS happens,
// document.cookie cannot read session cookies.

// ===== Detection checklist =====
// Code review for:
//   - innerHTML / outerHTML / document.write
//   - {!! ... !!} (Blade) / v-html / dangerouslySetInnerHTML
//   - Building HTML by string concatenation
//   - User input flowing into href / src without scheme validation

// ===== Recovery if you find one =====
// 1. Sanitise + escape at every render path
// 2. Rotate sessions if cookies could have been exposed
// 3. Audit similar paths in the codebase
// 4. Add a test that locks in the fix

// ===== Patterns to internalise =====
// - Treat input as data until you opt into HTML deliberately
// - Default-escape; sanitise allowlist when you need rich text
// - Strict CSP with nonces, never unsafe-inline
// - HttpOnly + Secure + SameSite cookies always

// ===== Pitfalls =====
// - Rolling a regex-based HTML sanitiser
// - Allowing javascript: URLs in href
// - Re-rendering stored HTML raw because 'we already sanitised on input'
// - Treating XSS as only a logged-in problem

Why it matters

XSS is a templating problem with three faces. Default-escape, sanitise via allowlist when you genuinely need HTML, ship strict CSP, and harden cookies. The three classes all reduce to the same rule: data must never be parsed as code.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
// Cross-Site Scripting (XSS): the attacker's script runs in the victim's browser
// in YOUR origin — so it sees the victim's cookies, DOM, and session.
// Caused by mixing untrusted data into HTML / JS without proper encoding.
Try it Yourself »

Exercise

Safe property for assigning untrusted strings as text.

el. = userInput;

Test yourself

Q1. XSS is a vulnerability in which…
Q2. The three classic shapes are…
Q3. The safest way to insert untrusted data as text is…

Discussion

Loading…