security/content-security-policy

content security policy Shipped

What this lens looks for

This applies to web apps only; a strict Content Security Policy must guard against XSS and injection. The policy should start strict — default-src 'none' — and add back only what is actually needed. Scripts SHOULD use a nonce-based source (script-src 'nonce-{random}' 'strict-dynamic'), which is more secure than domain allowlisting (allowlists are bypassable via JSONP/CDN-hosted scripts); flag any 'unsafe-inline' or 'unsafe-eval' in script-src — both MUST be absent. Clickjacking must be blocked with frame-ancestors 'self' (the CSP replacement for X-Frame-Options). New or changed policies SHOULD be deployed in report-only mode (Content-Security-Policy-Report-Only) first to surface violations before enforcing. A strict nonce-based CSP does NOT stop DOM-XSS flowing through injection sinks (innerHTML, document.write, eval-style setTimeout arguments), which execute without inline-script gating, so the CSP SHOULD be paired with Trusted Types: emit require-trusted-types-for 'script' and declare a named policy via trusted-types <policy-name>; that policy SHOULD back its conversions with a documented, vetted sanitizer (DOMPurify, or the Sanitizer API setHTML) rather than hand-rolled escaping, and SHOULD itself be rolled out in report-only mode first. Do NOT block Trusted Types adoption on universal native browser support — it is supported in Chromium and Safari, degrades safely where unsupported, and has a polyfill.

What its verifier checks

A CSP is present on web-app responses and starts from a strict baseline (default-src 'none' with only necessary sources added back); script-src uses a per-request nonce with 'strict-dynamic' rather than relying on domain allowlisting; script-src contains neither 'unsafe-inline' nor 'unsafe-eval'; frame-ancestors 'self' is set to prevent clickjacking; new/changed policies are rolled out via Content-Security-Policy-Report-Only before enforcement; Trusted Types is engaged for DOM-injection sinks via require-trusted-types-for 'script' plus a declared trusted-types policy backed by a vetted sanitizer and rolled out report-only first; Trusted Types adoption is not gated on universal native support.