🛡️ What is a Content Security Policy (CSP)?

A Content Security Policy (CSP) is an added layer of security that helps businesses and security teams mitigate certain types of client-side attacks.


Introduction

Content Security Policy (CSP) is a browser security mechanism that aims to mitigate Cross-Site Scripting (XSS) and some other attacks. It works by restricting the resources (such as scripts and images) that a page can load and restricting whether a page can be framed by other pages.

Content Security Policy

To enable CSP, a response needs to include an HTTP response header called Content-Security-Policy with a value containing the policy. The policy itself consists of one or more directives, separated by semicolons.

Threats

Mitigating cross-site scripting

By preventing the page from executing inline scripts, attacks like injecting

<script>
  document.body.innerHTML = 'defaced'
</script>

will not work.

By preventing the page from loading scripts from arbitrary servers, attacks like injecting

<script src="https://evil.com/hacked.js"></script>

will not work.

Mitigating packet sniffing attacks

In addition to restricting the domains from which content can be loaded, the server can specify which protocols are allowed to be used; for example (and ideally, from a security standpoint), a server can specify that all content must be loaded using HTTPS. A complete data transmission security strategy includes not only enforcing HTTPS for data transfer, but also marking all cookies with the secure attribute and providing automatic redirects from HTTP pages to their HTTPS counterparts. Sites may also use the Strict-Transport-Security HTTP header to ensure that browsers connect to them only over an encrypted channel.

CSP Directive Reference

This documentation is provided based on the Content Security Policy Level 2 W3C Recommendation, and the Content Security Policy Level 3 W3C Working Draft

Fetch Directives

Fetch directives tell the browser the locations to trust and load resources from. Most fetch directives have a certain fallback list specified in w3. This list allows for granular control of the source of scripts, images, files, etc.

  • default-src is a fallback directive for the other fetch directives. Directives that are specified have no inheritance, yet directives that are not specified will fall back to the value of default-src.
    CSP Level 1
  • script-src specifies the locations from which a script can be executed from. It is a fallback directive for other script-like directives.
    CSP Level 1
    • script-src-elem controls the location from which execution of script requests and blocks can occur.
    • script-src-attr controls the execution of event handlers.
  • style-src controls from where styles get applied to a document. This includes <link> elements, @import rules, and requests originating from a Link HTTP response header field.
    CSP Level 1
    • style-src-elem controls styles except for inline attributes.
    • style-src-attr controls styles attributes.
  • img-src specifies the URLs that images can be loaded from.
    CSP Level 1
  • connect-src provides control over fetch requests, XHR, eventsource, beacon and websockets connections.
    CSP Level 1
  • font-src specifies which URLs to load fonts from.
    CSP Level 1
  • object-src specifies the URLs from which plugins can be loaded from.
    CSP Level 1
  • media-src specifies the URLs from which video, audio and text track resources can be loaded from.
    CSP Level 1
  • child-src allows the developer to control nested browsing contexts and worker execution contexts.
    CSP Level 2
  • prefetch-src specifies the URLs from which resources can be prefetched from.
    CSP Level 3
  • manifest-src specifies the URLs that application manifests may be loaded from.
    CSP Level 3

Document Directives

Document directives instruct the browser about the properties of the document to which the policies will apply to.

  • sandbox(https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/sandbox) restricts a page's actions such as submitting forms.
    CSP Level 1
    • Only applies when used with the request header Content-Security-Policy.
    • Not specifying a value for the directive activates all of the sandbox restrictions. Content-Security-Policy: sandbox;
  • base-uri specifies the possible URLs that the <base> element can use.
    CSP Level 2
  • plugin-types limits the types of resources that can be loaded into the document (e.g. application/pdf).
    CSP Level 2
    3 rules apply to the affected elements, <embed> and <object>:
    • The element needs to explicitly declare its type.
    • The element's type needs to match the declared type.
    • The element's resource needs to match the declared type.
    EXAMPLE PLUGIN-TYPES POLICY
    plugin-types application/pdf;

Navigation directives instruct the browser about the locations that the document can navigate to.

  • form-action restricts the URLs which the forms can submit to.
    CSP Level 2
  • frame-ancestors restricts the URLs that can embed the requested resource inside of <frame>, <iframe>, <object>, <embed>, or <applet> elements.
    CSP Level 2
    • If this directive is specified in a <meta> tag, the directive is ignored.
    • This directive doesn't fallback to the default-src directive.
    • X-Frame-Options is rendered obsolete by this directive and is ignored by the user agents.
  • navigate-to restricts the URLs that the document may navigate to by any means. For example when a link is clicked, a form is submitted, or window.location is invoked. If form-action is present then this directive is ignored for form submissions. Removed from the CSP 3 Spec.

Reporting Directives

Reporting directives deliver violations of prevented behaviors to specified locations. These directives serve no purpose on their own and are dependent on other directives.

  • report-to defines a reporting group name defined by a Report-To HTTP response header.
    CSP Level 3
    See the Reporting API for more info.
  • report-uri directive is deprecated in CSP Level 3 in favor of the report-to directive, which is a URI that the reports are sent to.

Source List Reference

Source ValueExampleDescription
*img-src *Wildcard, allows any URL except data: blob: filesystem: schemes.
'none'object-src 'none'Prevents loading resources from any source.
'self'script-src 'self'Allows loading resources from the same origin (same scheme, host and port).
data:img-src 'self' data:Allows loading resources via the data scheme (eg Base64 encoded images).
https:img-src https:Allows loading resources only over HTTPS on any domain.
domain.example.comimg-src domain.example.comAllows loading resources from the specified domain name.
*.example.comimg-src *.example.comAllows loading resources from any subdomain under example.com.
'unsafe-inline'script-src 'unsafe-inline'Allows use of inline source elements such as style attribute, onclick, or script tag bodies (depends on the context of the source it is applied to) and javascript: URIs
'unsafe-eval'script-src 'unsafe-eval'Allows unsafe dynamic code evaluation such as JavaScript eval()
'nonce-'script-src 'nonce-rAnd0m'Allows an inline script or CSS to execute if the script (eg: <script nonce="rAnd0m">) tag contains a nonce attribute matching the nonce specified in the CSP header.
'sha256-'script-src 'sha256-xyz...'Allows an inline script or CSS to execute if its hash matches the specified hash in the header.
'strict-dynamic'script-src 'strict-dynamic'Enables an allowed script to load additional scripts via non-"parser-inserted" script elements (for example document.createElement('script'); is allowed).

Implementing Content Security Policy

You can deploy a CSP as a HTTP response header or an HTML meta tag.

To configure your web server to return the HTTP Content-Security-Policy header, use:

Content-Security-Policy: [directive] [resource type]

To use the HTML <meta> element to configure a policy, it looks like this:

<meta
  http-equiv="Content-Security-Policy"
  content="[directive] [resource type]"
/>