Content Security Policy (CSP) - HTTP | MDN
Skip to search
Content Security Policy (CSP)
Content Security Policy
(CSP) is a feature that helps to prevent or minimize the risk of certain types of security threats. It consists of a series of instructions from a website to a browser, which instruct the browser to place restrictions on the things that the code comprising the site is allowed to do.
The primary use case for CSP is to control which resources, in particular JavaScript resources, a document is allowed to load. This is mainly used as a defense against
cross-site scripting
(XSS) attacks, in which an attacker is able to inject malicious code into the victim's site.
A CSP can have other purposes as well, including defending against
clickjacking
and helping to ensure that a site's pages will be loaded over HTTPS.
In this guide we'll start by describing how a CSP is delivered to a browser and what it looks like at a high level.
Then we'll describe how it can be used to:
Control which resources are loaded
, to protect against XSS.
Restrict embedding
, to protect against clickjacking.
Upgrade insecure requests
, to help ensure that all resources are served over HTTPS.
Require the use of trusted types
, to help defend against client-side XSS.
Note that there's no dependency between the different use cases: if you want to add clickjacking protection but not XSS mitigation, you can just add the directives for that use case.
Finally we'll describe
strategies for deploying a CSP
and tools that can help to make this process easier.
CSP overview
A CSP should be delivered to the browser in the
Content-Security-Policy
response header. It should be set on all responses to all requests, not just the main document.
You can also specify it using the
http-equiv
attribute of your document's

element, and this is a useful option for some use cases, such as a client-side-rendered
single page app
which has only static resources, because you can then avoid relying on any server infrastructure. However, this option does not support all CSP features.
The policy is specified as a series of
directives
, separated by semi-colons. Each directive controls a different aspect of the security policy. Each directive has a name, followed by a space, followed by a value. Different directives can have different syntaxes.
For example, consider the following CSP:
http
Content-Security-Policy: default-src 'self'; img-src 'self' example.com
It sets two directives:
the
default-src
directive is set to
'self'
the
img-src
directive is set to
'self' example.com
The first directive,
default-src
, tells the browser to load only resources that are same-origin with the document, unless other more specific directives set a different policy for other resource types. The second,
img-src
, tells the browser to load images that are same-origin or that are served from
example.com
In the next section, we'll look at the tools available to control resource loads, which is the main function of a CSP.
Controlling resource loading
A CSP can be used to control the resources that a document is allowed to load. This is primarily used for protection against cross-site scripting (XSS) attacks.
In this section we'll first see how controlling resource loads can help protect against XSS, then at the tools CSP provides to control what resources are loaded. Finally we'll describe one particular recommended strategy, which is called a "Strict CSP".
XSS and resource loading
A cross-site scripting (XSS) attack is one in which an attacker is able to execute their code in the context of the target website. This code is then able to do anything that the website's own code could do, including, for example:
access or modify the content of the site's loaded pages
access or modify content in local storage
make HTTP requests with the user's credentials, enabling them to impersonate the user or access sensitive data
An XSS attack is possible when a website accepts some input which might have been crafted by an attacker (for example, URL parameters, or a comment on a blog post) and then includes it in the page without
sanitizing
it: that is, without ensuring that it can't be executed as JavaScript.
Websites should protect themselves against XSS by sanitizing this input before including it in the page.
Note:
A CSP can actually help protect against XSS in two different ways:
It can help ensure that input is sanitized before being used in the client: we discuss this later on in
Requiring trusted types
By controlling resource loads, a CSP can provide a defense in depth against XSS, protecting the website even if sanitization fails. This is the XSS defense that we will discuss in this section.
If sanitization fails, there are various forms the injected malicious code can take in the document, including:


An inline event handler:
html
onmouseover="console.log(`You've been hacked!`)"
src="thumbnail.jpg"
alt="" />
javascript:
URL:
html

A string argument to an unsafe API like
eval()
js
eval("console.log(`You've been hacked!`)");
By controlling resource loading, a CSP can provide protection against all of these. With a CSP, you can:
define the permitted sources for JavaScript files and other resources, effectively blocking loads from
disable inline script tags
allow only script tags which have the correct
nonce
or hash set
disable inline event handlers
disable
javascript:
URLs
disable dangerous APIs like
eval()
In the next section we'll go over the tools CSP provides to do these things.
Note:
Setting a CSP is not an alternative to sanitizing input. Websites should sanitize input
and
set a CSP, providing defense in depth against XSS.
Fetch directives
Fetch directives are used to specify a particular category of resource that a document is allowed to load — such as JavaScript, CSS stylesheets, images, fonts, and so on.
There are different fetch directives for different types of resource. For example:
script-src
sets allowed sources for JavaScript.
style-src
sets allowed sources for CSS stylesheets.
img-src
sets allowed sources for images.
One special fetch directive is
default-src
, which sets a fallback policy for all resources whose directives are not explicitly listed.
For the complete set of fetch directives, see the
reference documentation
Each fetch directive is specified as either the single keyword
'none'
or one or more
source expressions
, separated by spaces. When more than one source expression is listed: if any of the methods allow the resource, then the resource is allowed.
For example, the CSP below sets two fetch directives:
default-src
is given the single source expression
'self'
img-src
is given two source expressions:
'self'
and
example.com
The effect of this is that:
images must be either same-origin with the document, or loaded from
example.com
all other resources must be same-origin with the document.
In the next few sections we'll describe some of the ways you can use source expressions to control resource loads. Note that although we're describing them separately, these expressions can in general be combined: for example, a single fetch directive may include nonces as well as hostnames.
Blocking resources
To block a resource type entirely, use the
'none'
keyword. For example, the following directive blocks all

and

resources:
http
Content-Security-Policy: object-src 'none'
Note that
'none'
cannot be combined with any other method in a particular directive: in practice, if any other source expressions are given alongside
'none'
, then they are ignored.
Nonces
nonce
is the recommended approach for restricting the loading of


Hello world


`;

app.get("/", (req, res) => {
const nonce = crypto.randomUUID();
res.setHeader("Content-Security-Policy", `script-src 'nonce-${nonce}'`);
res.send(content(nonce));
});
On every request, the server generates a new nonce, inserts it into the CSP and into the


Hello world


`;

app.get("/", (req, res) => {
res.setHeader("Content-Security-Policy", csp);
res.send(content);
});
Note that:
We have a separate hash for every script in the document.
For the external script "main.js", we also include the
integrity
attribute, and give it the same value.
Unlike the example using nonces, both the CSP and the content can be static, because the hashes stay the same. This makes hash-based policies more suitable for static pages or websites that rely on client-side rendering.
Scheme-based policies
Fetch directives can list a scheme, like
https:
, to allow resources that are served using that scheme. This, for example, allows a policy to require HTTPS for all resource loads:
http
Content-Security-Policy: default-src https:
Location-based policies
Fetch directives can control resource loads based on where the resource is located.
The keyword
'self'
allows resources which are same-origin with the document itself:
http
Content-Security-Policy: img-src 'self'
You can also specify one or more hostnames, potentially including wildcards, and only resources served from those hosts will be allowed. This might be used, for example, to allow content to be served from a trusted CDN.
http
Content-Security-Policy: img-src *.example.org
You can specify multiple locations. The following directive allows only images that are same-origin with the current document, or are served from a subdomain of "example.org", or are served from "example.com":
http
Content-Security-Policy: img-src 'self' *.example.org example.com
Inline JavaScript
If a CSP contains either a
default-src
or a
script-src
directive, then inline JavaScript will not be allowed to execute unless extra measures are taken to enable it. This includes:
JavaScript included inside a

JavaScript in an inline event handler attribute:
html

JavaScript in a
javascript:
URL:
html
Click me
The
unsafe-inline
keyword can be used to override this restriction. For example, the following directive requires all resources to be same-origin, but allows inline JavaScript:
http
Content-Security-Policy: default-src 'self' 'unsafe-inline'
Warning:
Developers should avoid
'unsafe-inline'
, because it defeats much of the purpose of having a CSP. Inline JavaScript is one of the most common XSS vectors, and one of the most basic goals of a CSP is to prevent its uncontrolled use.
Inline



Example page!




It includes a script "main.js", which creates and adds another script, "main2.js":
js
console.log("hello");

const scriptElement = document.createElement("script");
scriptElement.src = `main2.js`;

document.head.appendChild(scriptElement);
We serve our document with a CSP like this:
http
Content-Security-Policy:
script-src 'sha256-gEh1+8U9S1vkEuQSmmUMTZjyNSu5tIoECP4UXIEjMTk='
The "main.js" script will be allowed to load, because its hash matches the value in the CSP. But its attempt to load "main2.js" will fail.
If we add
'strict-dynamic'
to the CSP, then "main.js" will be allowed to load "main2.js":
http
Content-Security-Policy:
script-src 'sha256-gEh1+8U9S1vkEuQSmmUMTZjyNSu5tIoECP4UXIEjMTk='
'strict-dynamic'
The
'strict-dynamic'
keyword makes it much easier to create and maintain nonce- or hash-based CSPs, especially when a website uses third-party scripts. It does make your CSP less secure, though, because if the scripts you include create

Clickjacking protection
The
frame-ancestors
directive can be used to control which documents, if any, are allowed to embed this document in a nested browsing context such as an