ESC

Type to search the knowledge base.

XSS Prevention Checklist

Actionable XSS checklist: sinks, sanitization, CSP, cookies, URLs, markdown, and PR review prompts.

intermediate3 min read
  • security
  • xss
  • checklist
  • csp
  • sanitization

This is the operator’s checklist companion to the conceptual XSS guide. Use it in PR review, threat modeling, and incident retros when user-controlled data touches the DOM.

Docs: OWASP XSS Prevention, Strict CSP, Trusted Types.

1. Prefer safe sinks

  • Use textContent / framework text bindings by default
  • No innerHTML / dangerouslySetInnerHTML / document.write with untrusted data
  • No eval, new Function, string setTimeout
el.textContent = user.name; // OK for text

2. If HTML is required

  • Sanitize with a maintained library (e.g. DOMPurify) and strict allowlist
  • Sanitize at the boundary closest to render (and/or server)
  • Don’t “regex out <script>”
el.innerHTML = DOMPurify.sanitize(html, { USE_PROFILES: { html: true } });

3. URLs and navigation

  • Allow only http:/https: (or internal paths) for href/src/location
  • Block javascript:, data: where inappropriate — safe URLs
  • Validate redirect targets — open redirects

4. Framework-specific

  • React: audit every dangerouslySetInnerHTML and URL attrs
  • Vue: audit v-html
  • Angular: avoid bypassing sanitizer APIs without review
  • Markdown/rich text: parser + sanitizer configured

5. Defense in depth

  • CSP with nonces/hashes; avoid unsafe-inline long-term — CSP
  • Trusted Types where supported
  • Session cookies HttpOnly; Secure; SameSite — cookies
  • No long-lived tokens in localStorage — JWT pitfalls

6. postMessage & embeds

7. Server still matters

  • API authz not only UI hiding
  • Escape server-rendered templates
  • Correct Content-Type + X-Content-Type-Options: nosniff for uploads

8. Test & monitor

  • Payload unit tests on sanitizer wrappers
  • Security headers in staging
  • CSP report-only during rollout
  • Bug bounty / automated scanner as assist, not sole gate

Interview out-loud

“XSS prevention is safe sinks first, sanitization when HTML is required, URL allowlists, CSP and Trusted Types, HttpOnly sessions, and careful postMessage/iframes. Checklists keep PR review honest when features demand rich HTML.”

Reviewer prompts

  • What is the asset (session, PII, money movement)?
  • What is the attacker capability (web, XSS, network, dependency)?
  • Which control fails closed if misconfigured?
  • Is the server still enforcing authz?
  • Any new third party, iframe, or URL sink?

Residual risk note

Browser controls reduce likelihood and impact; they do not eliminate bugs. Prefer defense in depth: safe defaults in code, strict headers, and monitoring (CSP reports, auth anomaly alerts). When product pressure weakens a control, write down the accepted risk and a revisit date.

Further depth

Teams often under-invest in this topic until an incident or CWV regression. Schedule a one-hour drill: reproduce the failure mode in DevTools, list the top three mitigations for your stack, and file tickets with owners. Revisit after the next major feature that touches networking, rendering, auth, or third parties — those are the moments regressions land. Keep primary documentation links in the runbook so on-call is not searching chat history at 2am.

Concrete artifacts to leave behind: a short architecture note, a CI assertion or header snapshot, and a dashboard panel (lab or field) that would have caught the last bug. Teaching the rest of the team the mental model matters as much as the one-line fix.

Further reading

Related guides