Content Security Policy
XSS prevention: Content security policy
As we've seen in the previous sections, protecting against XSS is hard and requires adherence to a large set of rules, depending on the complexity of your application.
Content Security Policy (CSP) is an added layer of security that helps to detect and mitigate certain types of attacks. A primary goal of CSP is to mitigate and report XSS attacks. XSS attacks exploit the browser's trust of the content received from the server. Malicious scripts are executed by the victim's browser because the browser trusts the source of the content, even when it's not coming from where it seems to be coming from. Configuring Content Security Policy involves adding the Content-Security-Policy HTTP header to a web page and giving it values to control resources the user agent is allowed to load for that page. For example, a page that uploads and displays images could allow images from anywhere, but restrict a form action to a specific endpoint.
Alternatively, the element can be used to configure a policy, for example: <meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
Specifying a Content Security Policy
You can use the Content-Security-Policy HTTP header to specify your policy, like this:
The policy is a string containing the policy directives describing your Content Security Policy. A policy is described using a series of policy directives, each of which describes the policy for a certain resource type or policy area. Your policy should include a default-src
policy directive, which is a fallback for other resource types when they don't have policies of their own. A policy needs to include a default-src
or script-src
directive to prevent inline scripts from running, as well as blocking the use of eval()
. A policy needs to include a default-src
or style-src
directive to restrict inline styles from being applied from a <style>
element or a style attribute.
Directives
Apart from default-src
, script-src
, and style-src
, other directives exist. A partial list is given below. For a full overview of all directives, see the Mozilla documentation. Note that some directives prevent against other attacks than XSS alone.
connect-src
Restricts the URLs which can be loaded using script interfaces
default-src
Serves as a fallback for the other fetch directives.
font-src
Specifies valid sources for fonts loaded using @font-face
.
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.
media-src
Specifies valid sources for loading media using the <audio>
, <video>
and <track>
elements.
script-src
Specifies valid sources for JavaScript. Two more fine-grained directives exist:
script-src-elem
: Specifies valid sources for JavaScript<script>
elements.script-src-attr
: Specifies valid sources for JavaScript inline event handlers.
style-src
Specifies valid sources for stylesheets. Two more fine-grained directives exist:
style-src-elem
: Specifies valid sources for stylesheets<style>
elements and<link>
elements withrel="stylesheet"
.style-src-attr
: Specifies valid sources for inline styles applied to individual DOM elements.
form-action
Restricts the URLs which can be used as the target of a form submissions from a given context.
frame-ancestors
Specifies valid parents that may embed a page using <frame>
, <iframe>
, <object>
, <embed>
, or <applet>
.
navigate-to
Restricts the URLs to which a document can initiate navigation by any means, including <form>
(if form-action is not specified), <a>
, window.location
, window.open
, etc.
Values
Each directive can have one or more values. For example, let's consider the following CSP:
This policy says that only scripts from https://code.jquery.com or https://google-analytics.com are allowed, or a script that has FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=
as its SHA-256 digest. This digest can be calculated over inline scripts or referenced scripts.
Typical values are the following:
*
: wildcard, allows any URLnone
: prevents loading resources from any source.self
: allows loading resources from the same origin (same scheme, host and port).data:
: allows loading resources via the data scheme (eg Base64 encoded images).domain.example.com
: allows loading resources from the specified domain name.*.example.com
: allows loading resources from any subdomain under example.com.https://cdn.com
: allows loading resources only over HTTPS matching the given domain.https:
: allows loading resources only over HTTPS on any domain.unsafe-inline
: allows use of inline source elements. This is ignored when hashes are used.unsafe-eval
: allows unsafe dynamic code evaluation such as JavaScript eval()nonce-
: allows script or style tag to execute if the nonce attribute value matches the header value. Example:<script nonce="2726c7f26c">alert("hello");</script>
sha256-XXX
: allow a specific script or style to execute if it matches the hash. Example: sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng=strict-dynamic
: propagate trust to all the scripts loaded by that root script. At the same time, any whitelist or source expressions such as 'self' or 'unsafe-inline' will be ignored.
Source attribution
Some parts of this page are based on Content Security Policy (CSP) by Mozilla Contributors, which is licensed under CC-BY-SA 2.5.
Last updated
Was this helpful?