Content Security Policy (CSP)
Overview
This page contains recommendations for the implementation of the Content Security Policy.
Content Security Policy (CSP) controls which resources are allowed to be loaded or executed by the browser. CSP is a defense-in-depth strategy that aims to mitigate Cross-Site Scripting attacks.
Syntax
The Content-Security-Policy
HTTP header follows the next syntax:
where <policy-directive>
consists of <directive> <value>
with no internal punctuation.
For example:
Directives
You can find all directives and their descriptions at MDN Web Docs: Content-Security-Policy - Directives.
CSP directives are divided into several classes:
Fetch directives control the locations from which certain resource types may be loaded. For example, those directives include:
default-src defines the default policy for other fetching directives.
frame-src specifies valid sources for nested browsing contexts loading using elements such as
<frame>
and<iframe>
.img-src specifies valid sources of images and favicons.
object-src specifies valid sources for the
<object>
and<embed>
elements.script-src specifies valid sources for JavaScript and WebAssembly resources.
style-src specifies valid sources for stylesheets.
Document directives establish the properties of a document or worker environment to which a policy applies. For example, those directives include:
Navigation Directives instruct the browser about the locations that the document can navigate to. For example, those directives include:
form-action restricts the URLs which can be used as the target of form submissions from a given context.
frame-ancestors specifies valid parents that may embed a page using
<frame>
,<iframe>
,<object>
, or<embed>
.
Reporting directives control the reporting process of CSP violations.
Source values
You can find all source values and their descriptions at MDN Web Docs: Content-Security-Policy - CSP source values.
Keyword values
none will not allow the loading of any resources.
self only allow resources from the current origin.
strict-dynamic the trust granted to a script in the page due to an accompanying
nonce
orhash
is extended to the scripts it loads.report-sample requires a sample of the violating code to be included in the violation report.
Unsafe keyword values
The use of unsafe keyword values significantly weakens the Content Security Policy.
unsafe-inline allows using of inline resources.
unsafe-eval allows using of dynamic code evaluation such as eval.
unsafe-hashes allows enabling specific inline event handlers.
Hosts values
Host allows the loading of resources from a specific host, path or specific URL. For example,
website.local
,website.local/api/
, orhttps://website.local/script.js
.Scheme allows the loading of resources over a specific scheme. For example,
https:
,http:
, ordata:
.
Other values
nonce-* is a cryptographic nonce (only used once) to allow scripts. For example,
nonce-DhcnhD3khTMePgXwdayK9BsMqXjhguVV
.sha*-*
sha256
,sha384
, orsha512
. Followed by a dash and then thesha*
value. For example,sha256-jzgBGA4UWFFmpOBq0JpdsySukE1FrEN5bUpoK8Z29fY=
.
General
Do not use CSP as main and single mitigation layer against Cross-Site Scripting attacks, see the Vulnerability Mitigation: Cross-Site Scripting (XSS) page.
Define CSP as restrictive as possible. Use CSP Evaluator to check the CSP for possible misconfigurations.
Use the basic Content Security Policy, see the Basic Content Security Policy section.
Use the
Content-Security-Policy
HTTP header for CSP delivering, see the Content-Security-Policy header section.Send the
Content-Security-Policy
HTTP header in each HTTP response.
Use the strict Content Security Policy, see the Strict Content Security Policy section.
Use the
Content-Security-Policy-Report-Only
HTTP header to report and log policy violations, see Content-Security-Policy-Report-Only header section.
Basic Content Security Policy
Use the following Content Security Policy as a starting point to define your policy:
This policy assumes that:
All resources are hosted by the same domain of a document.
There are no inline or
eval()
for scripts and style resources.There is no need for other websites to frame a website.
There are no form-submissions to external websites.
There is no need for loading plugins.
Use more tight Content Security Policy for defining a custom policy:
This policy allows images, scripts, AJAX, and CSS from the same origin and does not allow any other resources to load such as frame, media, etc.
Strict Content Security Policy
Use Nonce-based CSP or Hash-based CSP as a start point for defining your policy:
Nonce- and hashed-based CSP is a more effective strategy for mitigating XSS attacks. Choosing criteria:
Nonce-based CSP is more easier to implement and use it on multiple projects because it always has the same structure.
Hash-based CSP is preferable when pages are served statically or need to be cached by a user-agent or CDN. For example, single page web applications built with frameworks such as Angular, React, Vue, etc. Any changes made to a hashed inline script (including formatting) require the corresponding CSP hash header to be updated.
Nonce-based CSP
Nonce-based CSP sets a cryptographically strong random value with each <script>
tag that is validated by the browser during execution. Since an attacker can not guess a valid nonce they are not able to execute a malicious code because the browser will block it.
Do not create a middleware that replaces all script tags with
script nonce=...
because attacker-injected scripts will then get the nonces as well. You need an actual HTML templating engine to use nonces.Generate a nonce using a cryptographically strong generator, see the Cryptography: Random Generators page.
Use nonces of length 16+ bytes.
Use a new nonce for each response.
Hash-based CSP
Hash-based CSP sets the hash of JavaScript code foe each <script>
tag that is validated by the browser during execution. If there are any changes on that code, the hash will not match and the browser will block the execution.
<HASH>
must be a hash from all inline code within a legitimate inline <script>
tag. In case there are multiple inline <script>
tags, the syntax is as follows:
Calculate a hash of static inline code within
<script>
tag, see the Cryptography: Hashing page. You can use the following commands to generate a hash:
Implementation examples
Inline scripts
The strict CSP disables any JavaScript code placed inline in the HTML source by default. For example, the following inline code will be blocked by the strict CSP:
Move it to an external JavaScript file and import to the target document to avoid the block by the strict CSP:
Inlince event handlers
Inline event handlers, such as onclick
, onmouseover
, etc. are prevented to be executed by the strict CSP. For example, the following inline event handler code will be blocked by the strict CSP:
Refactor it as shown below to avoid the block by the strict CSP:
Inline JavaScript URI
Inline JavaScript URI such as <a href="javascript: ...">
is prevented to be executed by the strict CSP. For example, the following JavaScript URI scheme code will be blocked by the strict CSP:
Refactor it as shown below to avoid the block by the strict CSP:
CSP delivery
Content-Security-Policy header
Passing a CSP in the Content-Security-Policy HTTP header from a server is the best and secure CSP delivery that provides a full CSP defense.
For more detailed examples, see the Basic Content Security Policy and Strict Content Security Policy sections.
Content-Security-Policy Meta tag
In case the Content-Security-Policy HTTP header can not be set, you can use the Content-Security-Policy
<meta>
tag within HTML markup with the http-equiv
and content attributes. Unfortunately, this meta tag is not able to use framing protections, sandboxing or CSP violation logging endpoint.
Content-Security-Policy-Report-Only header
The Content-Security-Policy-Report-Only HTTP header allows reporting CSP violations without enforce them. This means, it can be used as a step to c reate, test and tight a CSP to fit your application needs without breaking functionality. Once you have found the best CSP directives and values for your application, you can deploy it as the Content-Security-Policy
header to enforce protection. However, it is possible combining both Content-Security-Policy
and Content-Security-Policy-Report-Only
headers, which is a good practice.
Violations from Content-Security-Policy-Report-Only
are printed on the browser's console or delivered to a defined endpoint using report-to
or report-uri
directives. report-to
directive requires the Reporting-Endpoints
HTTP header to be set and a named endpoint such as main-endpoint
.
References
Last updated