Skip to content

Stored, reflected, and DOM XSS: CSP level 3, trusted types, and framework-level sanitization

A deep dive into defending against modern Cross-Site Scripting (XSS) in React, Next.js, and Vue: Content Security Policy Level 3, Trusted Types, and DOM sinks.

By BugSnaps Security Research · · 8 min read

Cross-Site Scripting (XSS) remains a critical web vulnerability that allows attackers to execute malicious JavaScript in the context of an unsuspecting victim's browser session, stealing session tokens, intercepting keystrokes, or performing unauthorized actions on their behalf.

DOM XSS in modern Single Page Applications

Modern frontend frameworks like React and Vue provide built-in escaping for standard JSX bindings. However, DOM XSS frequently slips through when developers use escape-hatch APIs or insecure browser sinks:

  • `dangerouslySetInnerHTML`: rendering user-supplied markdown, HTML descriptions, or third-party widgets without rigorous DOMPurify sanitization.
  • Insecure URL schemes: passing user-controlled strings into `<a href={url}>`, allowing `javascript:alert(1)` execution upon user click.
  • Unsafe DOM sinks: passing `window.location.search` or `hash` values directly into `eval()`, `document.write()`, or `setTimeout()`.

Defense in depth with Content Security Policy Level 3

A robust Content Security Policy (CSP) acts as an indispensable defense-in-depth safety net. By deploying a strict, nonce-based CSP (`script-src 'nonce-...' 'strict-dynamic'`), browsers refuse to execute unauthorized inline scripts or externally injected script tags even if an application-layer injection flaw exists.

Combine framework-level context-aware sanitization with a strict nonce-based CSP and Trusted Types to eliminate XSS risks across your application portfolio.

Run a real pentest on your app - free.

Sign in, prove you own the domain, and MyPentest maps and tests it. No credit card.