3. HTTP Content Security Policy
1. CSP INTRODUCTION
Content-Security-Policy (CSP) is a special HTTP response header that tells the browser what are the safe sources of the content for the page it is going to load.
When those safe sources are specified, it prevents the hacker from tricking the browser into loading and running malicious scripts in the user’s browser, injecting iframes with some malicious or unauthorized content, displaying fake images or basically injecting anything from a remote untrusted domain.
CSP can also be used to ensure that all the content is loaded via HTTPS, and it also prevents Clickjacking by instructing the browser that it shouldn’t allow the certain page to be loaded in an iframe.
In the right pane, there is an example of a properly set Content-Security-Policy header.
Content-Security-Policy: script-src ‘strict-dynamic’ ‘nonce-RandomValue’ ‘unsafe-inline’ http: https:https://codebashing.com; object-src ‘none’;
What this policy does:
-
It allows all scripts that have the RandomValue nonce specified and propagates the trust to all the scripts loaded by these scripts;
-
It will ignore scripts from https://codebashing.com unless they have the nonce specified;
-
It specifies the schemas that may be used to retrieve the scripts: http or https;
-
It disallows objects that can be used to execute JavaScript like <object >, <embed > or <applet > tags.
2. CSP PRECAUTIONS
As we’ve just learned, Content-Security-Policy header instructs the browser which sources of scripts (and other content) are trusted, and the browser runs only those scripts that were taken from those trusted sources and ignores all the inline scripts and HTML event attributes (unless it’s instructed otherwise).
It is important to emphasize:
CSP doesn’t prevent the injection of malicious scripts itself. Those scripts can be injected by some hacker. But they will not run, because CSP will instruct the browser to execute only the scripts taken from the trusted sources specified in the policy.
So CSP shouldn’t be used as the only security control to prevent XSS or injection of malicious content. It should be used as a part of the defense-in-depth strategy against XSS and other vulnerabilities.
In the right pane, there is an example of a badly set Content-Security-Policy header.
Content-Security-Policy: script-src https://codebashing.com unsafe-inline’ ‘unsafe-eval’; img-src * ; default-src ‘self’
What does this policy do?
-
It allows scripts loaded from https://codebashing.com
-
It allows script from inline resources
-
It allows usage of eval() and similar unsafe JavaScript methods
-
It allows images from any source
-
When the type of content is not specified, it falls back to the default policy that allows content loaded from the current origin.
3. CSP CONFIGURATION NOTES
It is important to mention that the Content Security Policy must be thoroughly tested prior to the implementation in the production environment. CSP misconfiguration can easily break the application’s functionality and ruin the user experience.
A misconfigured CSP is likely to be loosened or turned off, and a loosened CSP in most cases is as insecure as a missing CSP.
To make the testing procedure easier, CSP has a reporting functionality (will be discussed later in this lesson).
. CSP VERSIONS
CSP is constantly evolving. The current version of CSP is “level 2”. “Level 3” version of it exists but it is still in a draft, nevertheless modern browsers support most of it. (CSP header can be not compatible with old browsers. Browsers that don’t support CSP just ignore the CSP header.)
Some directives that we are going to discuss in this lesson behave differently in versions 2 and 3, and in this case, the lesson will describe the behavior in version 3.
CSP DIRECTIVES TYPE: FETCH
This set of directives controls locations used to load different types of resources.
Please note that in order to mitigate XSS, you should define either default-src
and script-src
directives or object-src
and script-src
directives.
In the right pane, click the directive or the keyword you want to explore, and the description will appear instantly
default-src
The default-src directive defines a default source of content for the webpage. It is used as a fallback when a specific directive is not defined. All fetch directives fall back to default-src if they are not defined.
object-src
This directive defines sources for <object>, <embed> and <applet> tags. Note that using these tags allows for arbitrary javascript execution, so it must be included into the policy in order to prevent XSS.
script-src
This directive defines sources of JavaScript like <script>, javascript:, eval(), etc.
It should be configured carefully because misconfiguration usually leaves an opportunity to bypass CSP.
The directive allows more granular configuration using keywords. Note that these keywords turn off some security features leaving CSP bypassable.
child-src
This directive is deprecated in CSP Level 3. Usage of frame-src and worker-src is recommended instead.
The directive defines sources for web workers and nested browsing contexts loaded using <iframe> or <frame> tags.
connect-src
The directive restricts usage of XMLHttpRequests, Fetch, WebSockets, EventSource and <a ping=”URL”>, only the URLs specified in the policy can be loaded using methods mentioned previously.
font-src
The directive specifies sources of fonts.
frame-src
The directive specifies valid sources for nested browsing context using <iframe> or <frame>.
img-src
The directive specifies sources of images.
manifest-src
The directive specifies sources of a web application manifest.
media-src
The directive specifies sources of media loaded in <audio> or <video> tags.
prefetch-src
The directive specifies the URL from which resources can be prefetched or pre-rendered.
style-src
The directive specifies sources of style sheets.
worker-src
The directive specifies sources of web workers.
unsafe-inline
Without this keyword, CSP will trust only scripts loaded from the specified resources. It won’t permit inline scripts residing on the webpage between <script>, <style> tags, in javascript: and event handlers.
This keyword allows inline script sources and thus removes the protection against XSS that CSP provides.
If there is no possible way to avoid using inline javascript, then nonce or hash source should be used.
unsafe-eval
This keyword allows usage of functions that evaluate code presented as a string, e.g. eval(), Function(), etc.
strict-dynamic
This keyword is used with a nonce or hash source, e.g. script-src ‘strict-dynamic’ ‘nonce-RandomValue’ or script-src ‘strict-dynamic’ ‘sha-256-base64EncodedHash’.
The nonce received in the header should be a part of <script>, e.g. <script nonce=”RandomValue” src=”script URL”>, thus the browser understands that this script is trusted and can be executed.
The hash received in the header is the base64 representation of a sha256 (384 or 512) hash of the script.
This script-dynamic keyword indicates that all the scripts loaded by the script with a nonce or hash are trusted and can be executed.
6. CSP DIRECTIVES TYPE: DOCUMENT
These directives control the properties of a document or worker environment to which a content security policy applies.
In the right pane, click the directive you want to explore, and the description will appear instantly.
base-uri
The directive restricts the URLs that can be used in <base> element which defines the base URLs to be prepended to relative URLs used in the page.
plugin-types
The directives defines types of plug-ins used in <embed>, <object>, <applet> tags, e.g. flash objects or java applets.
sandbox
The directive applies a sandbox attribute to the current page. It behaves like a sandbox attribute used in <iframe> allowing to restrict execution of scripts and plug-ins, block pop-ups, etc.
disown-opener
The directive instructs a browser to set window.opener object to null when the user is navigated from a CSP-protected page to a new tab or window. Check out the Reverse Tabnabbing lesson to understand what purpose this directive serves.
Note that the directive is not finalized; alternative security controls should be used.
7. CSP DIRECTIVES TYPE: NAVIGATION
These directives restrict URLs that are used to navigate the user from the current page using different HTML tags.
In the right pane, click the directive you want to explore, and the description will appear instantly.
form-action
The directive specifies the URLs that can be used as targets of form submission, e.g. targetURL in <form action=”targetURL” method=”post”>.
frame-ancestors
The directive specifies sources that may open the page in <iframe>, <frame>, <applet>, <object> and <embed> tags.
The directive partially overlaps with the X-FRAME-OPTIONS HTTP header and serves the same purpose.
Check Clickjacking lesson to learn more about X_FRAME_OPTIONS and frame-ancestors.
navigate-to
The directive restricts the URLs to which document can initiate navigation using any navigation means.
Note that the directive is a part of CSP level 3, thus it is not published yet. There also can be support issues among browsers.
8. CSP DIRECTIVES TYPE: REPORTING
To make the CSP configuration process easier, one can use a reporting functionality that is built into the CSP (it works according to the reporting API specification at https://w3c.github.io/reporting/).
Location of report collection service can be set using report-to
or report-uri
directives. Also, CSP has a report-only mode that should be used for testing CSP settings. The report-only mode is activated by using Content-Security-Policy-Report-Only header.
In the right pane, click the directive you want to explore, and the description will appear instantly.
report-to
This directive specifies a reporting group that should be used to send reports. Reporting groups are set in Report-To response header. Reporting group is created according to the reporting API (https://w3c.github.io/reporting/).
report-uri
This directive specifies the URL that the user-agent should use to report CSP violation.
Note that this directive is deprecated in CSP level 3 and the usage of Report-To is recommended.
Currently, Report-To is not widely supported by browsers, thus the usage of both directives is recommended for the backward compatibility. If Report-To is presented and supported by the browser, then report-uri directive is ignored.
9. CSP DIRECTIVES TYPE: OTHER
In the right pane, click the directive you want to explore, and the description will appear instantly.
block-all-mixed-content
This directive prevents loading of any page components via HTTP if the page is loaded via HTTPS.
require-sri-for
This directive makes subresource integrity (SRI) usage mandatory for scripts or/and style sheets. For example, SRI allows to specify a loaded script hash and to check that script hasn’t changed.
upgrade-insecure-requests
This directive instructs the user-agent to upgrade non-navigational requests from HTTP to HTTPS.
10. GOOD CSP TIPS
So, how to configure the effective Content Security Policy? We have some tips for you:
1. CSP should restrict at least sources of scripts and objects.
2. Use a whitelist of specific scripts containing the nonce specified in the policy or compare the script hash with the hash specified in the policy.
3. Avoid using unsafe-inline
and unsafe-eval
or at least use them with a nonce or a hash.
4. Test your policy before going to production.
5. Use CSP only in the report-only
mode for a pilot run on production.