Content Security Policy (CSP)

The Content Security Policy (CSP) header tells the browser what resources (e.g. scripts, images, fonts) can be trusted. Resources that violate CSP will not be run/fetched by the browser.

CSP is used to mitigate Cross Site Scripting (XSS) and data injection attacks.

Reporting CSP

Since enforcing CSP right off the bat may break your site, you should consider only reporting CSP violations first.

You decide which CSP directives are enforced or only-reported by using the following headers, and setting the report-uri <url> directive (both headers are honored):

  • Content-Security-Policy (enforced)
  • Content-Security-Policy-Report-Only (report only)

Structure of CSP report

On CSP violations, the browser would send a JSON POST request like the following to your report-uri endpoint.

  • blocked-uri will not include the full path (only the origin) for cross-origin requests. This is to prevent leaking sensitive information about cross-origin resources.
  • disposition encorce or report, depending on which CSP header is used.
{
  "csp-report": {
    "document-uri": "http://example.com/signup.html",
    "referrer": "",
    "blocked-uri": "http://example.com/css/style.css",
    "violated-directive": "style-src cdn.example.com",
    "original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports",
    "disposition": "report"
  }
}

Response headers

Content-Security-Policy

Enforces CSP.

You can specify Content-Security-Policy header multiple times, e.g. to have different policy violations report to different report-uri URLs, or to have some policy violations not reported.

All policies are evaluated and reported individually (Csper). Additional policies can only further restrict the protected resources (MDN).

Content-Security-Policy: <policy-directive>
Content-Security-Policy: <policy-directive>; <policy-directive>; ...

Content-Security-Policy-Report-Only

Only reports CSP violation.

You can specify Content-Security-Policy-Report-Only header multiple times, e.g. to have different policy violations report to different report-uri URLs.

Content-Security-Policy-Report-Only: <policy-directive>
Content-Security-Policy-Report-Only: <policy-directive>; <policy-directive>; ...

CSP source list

All CSP directives that end with -src can be filled with a source list, which is space-separated list of the following values. For example, you may specify:

Content-Security-Policy: script-src 'self' www.mysite.com api.mysite.com
Keyword
  • 'none' don't load any resources.
  • 'self' only load resources from the same origin (same scheme, host, and port).
Any domain
  • * allows loading from any URLs, except from data://, blob://, and filesystem:// schemes.
  • https: allows loading from https:// scheme. (You can also specify other schemes, like data: for example.)
Specific domain
  • https://domain.com allows loading only from https:// scheme matching the specified domain.
  • domain.example.com allows loading from the specified domain.
  • *.example.com allows loading from any subdomain of example.com.
Hash/nonce
  • 'sha256-<base64hash>' allows an inline script or CSS to execute if its hash matches the specified hash. You can also use sha384 or sha512.
  • 'nonce-<base64hash>' allows an inline script or CSS to execute if has nonce="..." attribute matching the specified nonce. (The nonce should be a secure random string, and should not be reused.)
Unsafe
  • 'unsafe-eval' allows use of eval() and similar methods for creating code from strings.
  • 'unsafe-inline' allows inline sources like <script>, <style>, javascript:// URLs, and event handler attributes (e.g. onclick="...").
  • 'unsafe-hashes' allows inline sources in event handler attributes (e.g. onclick="..."), but not <script>, <style>, and javascript:// URLs.
Others
  • 'strict-dynamic' if a script trusted via nonce/hash loads additional scripts, trust those scripts as well.
  • 'report-sample' only for script-src, report a sample of the violating code in the CSP report.

CSP directives

Fetch directives

Default
  • default-src fallback for other directives.
Scripts
  • script-src lists trusted sources for JavaScript.
  • script-src-elem lists trusted sources for <script> elements.
  • script-src-attr lists trusted sources for JavaScript event handlers (e.g. onclick).
Styles
  • style-src lists trusted sources for CSS.
  • style-src-elem lists trusted sources for <style> and <link rel="stylesheets"> elements.
  • style-src-attr lists trusted sources for style="..." attributes.
Assets
  • image-src lists trusted sources for images.
  • fonts-src lists trusted sources for fonts loaded using @font-face.
  • media-src lists trusted sources for media, e.g. <audio> and <video> elements.
  • object-src lists trusted sources for objects, e.g. <object> and <embed> elements.
Others
  • connect-src lists URLs that can be loaded from script interfaces (e.g. AJAX and fetch() requests). Connection to unallowed URLs will yield an emulated 400 (Bad Request) response.
  • child-src lists trusted sources for web worker scripts and nested browsing contexts (e.g. <frame> and <iframe> elements).
  • worker-src lists trusted sources for web worker scripts.
  • frame-src lists trusted sources for nested browsing contexts (e.g. <frame> and <iframe> elements).

Navigation directives

  • form-action lists URLs to which forms may be submitted.
  • base-uri lists valid parents that may embed a page using <frame>, <iframe>, <object>, or <embed>.
  • base-uri lists URLs to which the document can navigate by any means

Document directives

  • base-uri lists which URLs can be used in the document's <base> element.
  • sandbox enables sandboxing for frames, similar to <iframe sandbox="...">. No values mean restrict all. Otherwise, specify space-separated values of the following:
    • allow-forms allows the frame to submit forms
    • allow-modals allows the frame to open modal windows (e.g. via alert())
    • allow-orientation-lock allows the frame to lock screen rotation
    • allow-pointer-lock allows the frame to use Pointer Lock API (e.g. to read or change mouse pointer movement)
    • allow-popups allows the frame to open popup (e.g. via window.open() or target="_blank")
    • allow-popups-to-escape-sandbox when the frame opens a popup, don't force sandboxing flags it (allows it to have new or different restrictions)
    • allow-presentation allows the frame to start presentation session
    • allow-same-origin allows the frame content to be treated as being from its normal origin (by default, sandbox directive forces the “different origin” policy for the iframe, even if its src points to the same site)
    • allow-scripts allows the frame to run scripts (but not open popup windows)
    • allow-top-navigation allows the frame to navigate the top-level browsing context (e.g. via top.location = ... or <a target="_top">)
    • allow-top-navigation-by-user-activation allows the frame to navigate the top-level browsing context, but only if initiated by a user gesture

Reporting directives

  • report-uri where to send CSP violation reports.

Other directives

  • upgrade-insecure-requests treat all insecure URLs in the page as if they have been replaced with secure URLs (HTTPS). Navigation links to external sites (e.g. <a href="http://external-site.com">) are not upgraded.
  • trusted-types restricts the creation of Trusted Type policies (via trustedTypes.createPolicy). Accepts:
    • 'none' disallows creating any Trusted Type policy
    • 'allow-duplicate' creating policies with a name that was already used
    • space-separated Trusted Type policy names
  • require-trusted-types-for controls the data passable to DOM XSS "sink functions" like Element.innerHTML = '...'. When used, those functions only accept typed values created by Trusted Type policies, and reject strings (MDN). Accepts:
    • 'script' disallows using strings with DOM XSS injection sink functions (MDN)

Read More

References