Security

Content Security Policy Builder

Build a Content-Security-Policy header and have it reviewed for the weaknesses that make a CSP ineffective.

Start from a preset
Directives

Fallback for every fetch directive that is not set explicitly.

Where JavaScript may be loaded from. Falls back to default-src when unset.

Where stylesheets may be loaded from. Falls back to default-src when unset.

Where images may be loaded from. Falls back to default-src when unset.

Where fonts may be loaded from. Falls back to default-src when unset.

Targets for fetch, XHR, WebSocket and EventSource. Falls back to default-src when unset.

Where audio and video may be loaded from. Falls back to default-src when unset.

Sources for <object>, <embed> and <applet>. Falls back to default-src when unset.

What may be embedded in frames on this page. Falls back to default-src when unset.

Sources for Worker, SharedWorker and ServiceWorker. Falls back to default-src when unset.

Where the web app manifest may be loaded from. Falls back to default-src when unset.

What the <base> element may set the document base URL to.

Where forms on this page may submit to.

Who may embed this page. The modern replacement for X-Frame-Options.

Rewrites http:// subresource requests to https://.

Where violation reports are POSTed. Deprecated in favour of report-to.

Reporting group (declared via the Reporting-Endpoints header).

Header
Content-Security-Policy: default-src 'none'; script-src 'nonce-{RANDOM}' 'strict-dynamic' 'unsafe-inline' https:; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests

Deploy as Report-Only first. It reports violations without blocking anything, so you can find what the policy would break before it breaks it.

Review
Medium findings
  • script-src

    `https:` allows scripts from every HTTPS origin. Restrict this to the specific hosts you load code from.

  • script-src

    'unsafe-inline' is present but 'strict-dynamic' is too, so supporting browsers ignore it. This is the intended fallback pattern for older browsers.