🎉 Requestly joins BrowserStack to build the future of application testing. Read more

HTTP Headers

Content Security Policy

HTTP Header

The HTTP Content-Security-Policy response header enables website administrators to specify which resources the user agent can load for a particular page. Generally, policies involve defining server origins and script endpoints, with few exceptions.
This mechanism is a vital security measure to prevent cross-site scripting attacks.

For comprehensive details on how a Content Security Policy (CSP) is implemented, its appearance, and best practices for deployment, refer to the Content Security Policy (CSP) guide.

Syntax

Content-Security-Policy: <policy-directive>; <policy-directive>

where <policy-directive> consists of:
<directive> <value> with no internal punctuation.

Directives

Fetch directives

Fetch directives control the origins from which different types of resources can be loaded. These policies enhance security by limiting or allowing content based on its source.

All fetch directives can be set to ‘none’ to completely block a resource type or list one or more source expressions that are permitted origins. These source expressions include host sources, scheme sources, or special keywords, and their syntax is detailed in the fetch directive syntax section.

Examples of fallback behavior include:

  • If img-src is missing but default-src is present, the default-src policy applies to images.
  • If script-src-elem is missing but script-src is present, the latter applies to script elements.

Common fetch directives include child-src for web workers and nested browsing contexts, connect-src for script interfaces, default-src as a fallback, font-src for fonts, img-src for images and icons, and more. Some directives might be marked as experimental or deprecated.

Document directives

Document directives establish policies for properties of documents or worker environments. They manage aspects like URL restrictions and sandboxing.

Navigation directives

Navigation directives specify the URLs or destinations where users are permitted to navigate or submit forms, imposing limits on potential navigation targets.

Reporting directives

Reporting directives specify where Content Security Policy violation reports should be sent. They facilitate monitoring and debugging by sending details about security policy violations to designated endpoints.

Other directives

Additional directives include require-trusted-types-for, which enforces Trusted Types at points where DOM XSS injections can occur, trusted-types for allowing specific policies, and upgrade-insecure-requests to automatically change insecure URLs to HTTPS.

Deprecated directives

Some directives, such as block-all-mixed-content and report-uri, are no longer recommended. They should be replaced by modern alternatives like upgrade-insecure-requests and report-to.

Fetch directive syntax

Fetch directives accept either a single value ‘none’ to block resources or one or more source expressions that specify valid origins. Source expressions come in various formats, including:

  • <host-source>: specifies a host or IP address, with optional scheme, port, and path. Wildcards like * can match subdomains or ports.
  • <scheme-source>: specifies a URL scheme such as https: or wss:.
  • <nonce-<nonce_value>>: a random value generated by the server for scripts or styles.
  • <hash_algorithm-hash_value>: a cryptographic hash of inline scripts or styles, allowing integrity verification.
  • ‘self’: resources from the same origin as the document.
  • ‘unsafe-inline’: allows inline scripts or styles, which reduces security.
  • ‘unsafe-eval’: permits the execution of code from strings, generally discouraged.
  • ‘wasm-unsafe-eval’: allows WebAssembly to be compiled from strings.
  • ‘strict-dynamic’: trust is extended to dynamically loaded scripts initiated by a trusted script.

Source expressions should be formatted according to the security considerations for each resource type, typically with unquoted host or scheme sources and quoted source expressions as needed.

Nonces and Hashes

Nonces are unique, Base64-encoded strings generated per response to permit specific inline scripts or styles. For example:

'nonce-base64-encoded-string'

Hashes specify the cryptographic hash of inline scripts or styles for integrity verification, such as:

'sha256-base64hash'

When hashes or nonces are used, inline scripts or styles must include matching attributes. They improve security by allowing specific inline code while preventing injection attacks.

<host-source>

The URL or IP address of a host that is a valid source for the resource, with optional scheme, port, and path. Wildcards allow matching subdomains or all ports. Path matching can be prefix or exact, providing detailed control over resource origins.

<scheme-source>

The URL scheme, such as https: or wss:. Secure upgrades are permitted, meaning resources requested over HTTP can be loaded over HTTPS.

‘self’

Resources can only be loaded from the same origin as the document. If the document is served over HTTP, this allows HTTPS equivalents; the same applies to WebSocket schemes.

‘unsafe-eval’

Enables JavaScript evaluation functions like eval(), which are disabled by default or under strict CSPs for security reasons. Its use should be avoided unless essential, as it weakens content security.

‘wasm-unsafe-eval’

Allows WebAssembly code to be compiled from strings, bypassing default restrictions. Use with caution to avoid security risks.

‘unsafe-inline’

Permits inline JavaScript and CSS, including inline event handlers or style attributes. This significantly reduces security but might be necessary for legacy or specific applications.

‘unsafe-hashes’

Allows the execution of inline code based on hash expressions, enabling more specific control over inline scripts and styles. Use with caution, as allowing hashes can still introduce risks.

‘inline-speculation-rules’

Permits loading inline <script> elements that have a type attribute set to speculationrules.

‘strict-dynamic’

Extends trust from nonces or hashes to dynamically loaded scripts, allowing scripts created at runtime to inherit the same security policy. This is useful for scenarios involving dynamic script loading.

‘report-sample’

If included in a directive related to scripts or styles and violations occur, the violation report will include a sample of the content of the first blocked resource, aiding in debugging and security analysis.

CSP in workers

Workers are generally not subject to the CSP of the parent document unless their origin is a unique identifier like data: or blob:. To define policies for workers, set the Content-Security-Policy header for the request of the worker script.

Multiple content security policies

It is possible to specify multiple policies using multiple Content-Security-Policy headers, Content-Security-Policy-Report-Only headers, or <meta> tags.

Example

Disable unsafe inline code and only allow HTTPS resources:

This HTTP header sets the default rule to only permit loading resources (like images, fonts, and scripts) over HTTPS. Since the unsafe-inline and unsafe-eval directives are not included, inline scripts will be blocked.

Content-Security-Policy: default-src https:

The same restrictions can be applied using the HTML <meta> element.

<meta http-equiv="Content-Security-Policy" content="default-src https:" />

Allow inline code and HTTPS resources, but disable plugins:

This policy could be used on an existing site that relies heavily on inline code that is difficult to refactor. It ensures resources are loaded only over HTTPS and disables plugins:

Content-Security-Policy: default-src https: 'unsafe-eval' 'unsafe-inline'; object-src 'none'

Report but don’t enforce violations when testing:

This example applies the same restrictions as the previous one but uses the Content-Security-Policy-Report-Only header and the report-to directive. This approach is useful during testing to log violations without preventing code execution.

The endpoints (URLs) where reports are sent are defined using the Reporting-Endpoints HTTP response header.

Reporting-Endpoints: csp-endpoint="https://example.com/csp-reports"

A specific endpoint is then chosen as the report destination within the CSP policy using the report-to directive.

Content-Security-Policy-Report-Only: default-src https:; report-uri /csp-violation-report-url/; report-to csp-endpoint

Note that the report-uri directive is also included above because report-to is not yet widely supported by browsers.

Refer to the Content Security Policy (CSP) implementation guide for more examples.

How to Modify Header using Requestly

Requestly is a powerful Chrome extension that allows you to modify HTTP headers, including the Content-Security-Policy header. This is especially useful for testing how your application behaves with different security policies during development or debugging. Steps to Modify the Content Security Policy Header:

  1. Install and open the Requestly Chrome extension. You can find it on the Chrome Web Store.
  2. Create a new rule: Click on “Create Rule” and choose “Modify Headers” from the list of available rule types.
  3. Add a new header modification:
    • Under “Action”, select “Add” or “Override”.
    • In the “Header Name” field, enter Content-Security-Policy.
    • In the “Header Value” field, enter your desired policy directives (e.g., default-src ‘self’; img-src *; script-src ‘none’).
  4. Set the URL condition: Specify the URL or pattern where this header change should apply (e.g., https://your-website.com/*).
  5. Save the rule.

Using Requestly to modify the Content Security Policy header helps you test how different security settings affect your website. This is key to ensuring your site blocks unwanted content while still functioning correctly.