Skip to main content

About Content Security Policy

This section explores Content Security Policy (CSP) and how a CSP header can help prevent common vulnerabilities.

Content Security Policy directives are defined in HTTP response headers, called CSP headers. The directions instruct the browser on trusted content sources and include a list of sources that should be prevented. In addition, the Content-Security-Policy header declares content restrictions by specifying server origins and script endpoints.

A Content-Security-Policy header provides a framework for developers to control privilege and the loading of resources for the application process. It helps reduce the risk of attacks that leverage the need for loading resources within a malicious context. With properly formulated CSPs, the developers can access a reporting mechanism to detect and document security flaws exploited in production. All major browsers support CSPs, making the standard header an essential application security layer.

CSPs enable granular control over:

  • Inline script execution.
  • How inline styles are applied.
  • Dynamic code execution.

CSP directives fall under various categories depending on use-case and content attribute. These include:

Fetch directives

These directives specify the locations for loading certain resource types. Fetch directives include:

  • child-src: defines the script sources on your allowlist for browsing context loaded in frames and web workers.
  • connect-src: specifies the URLs to be loaded using scripts.
  • default-src: the fallback directive for all fetch directives. This policy directive defines the default source list for other fetch directives.
  • object-src: defines allowed sources for <applet>, <embed> and <object> elements.
  • style-src: provides a list of valid sources for cascading style sheets.

Document directives

Document directives help control the properties of the working environment or document where a policy will be effective. These include:

  • sandbox: provides a sandbox for a specified resource similar to inline script elements.
  • base-uri: specifies the URLs allowed in the base element of the document.

These directives govern the locations of a form submission or where the document initiates any navigations. They include:

  • form-action: specifies the URLs that act as targets for the submission of form elements.
  • frame-ancestors: restricts the parents to be embedded on the web page using the <frame>, <object>, <iframe>, <applet> and <embed> elements.

Reporting directives

These directives govern how CSP violations are documented and reported. They include:

  • report-to: initiates a security policy violation event.
  • report-uri: a policy directive instructing the client environment to report any attempt to violate CSP specifications.

Other directives include:

  • require-sri-for: enforces the use of Subresource Integrity (SRI) for the style attribute and page script sources.
  • trusted-types: used to specify a list of accepted, non-spoofable typed values, thus mitigating DOM-based XSS attacks.
  • require-trusted-types-for: this policy directive enforces the trusted-types policy on scripts that act as sinks for DOM-based XSS.
  • upgrade-insecure-requests: in websites with numerous insecure legacy URLs, this policy instructs the browser to treat every insecure URL as if it has been replaced with an HTTPS secure URL.

Vulnerabilities you can prevent using CSP

CSPs protect web applications from several vulnerabilities and attacks, including:

XSS attacks

CSPs form the first line of defense against XSS attacks as they block executing malicious scripts that untrusted sources inject. To reduce the XSS attack surface, developers restrict loading resources using the script-src self directive. This directive only allows the page to load scripts originating from the same server hosting the page. The script-src <allowed-web-url> enables the page to load scripts from a specific domain. Besides adding resource origins to your allowlist, CSPs help mitigate XSS attacks using hashes and nonces.

A nonce is a random value specified in the CSP so that it is used to load scripts in a tag. The CSP checks the nonce match source list, ensuring that the values match; otherwise, the script is executed. A hash-algo component of a trusted script contents can also be specified in a CSP directive. The script only runs when the actual script hash matches the value in the CSP directive.

Clickjacking attacks

The frame-ancestors self CSP directive governs that only pages with the exact origin can frame the policy page. Developers can also wholly prevent framing using the frame-ancestors none directive. CSPs can be used alongside the X-Frame-Options header to prevent clickjacking attacks. CSPs are more effective since they allow for the specification of multiple domains. The policy also validates every external resource in the parent frame hierarchy, enabling stronger protections against frame hijacking attacks.

Dangling markup attacks

CSPs protect against dangling markup attacks by restricting the page origin of images to be loaded. The img-src self directive only allows images to be loaded from the exact origin. The img-src <allowed-web-url> directive governs the page to load images from a specific domain. The img tag helps prevent dangling markup attacks since it makes it easy to capture input data with minimal user interaction.

Other attacks that CSPs mitigate include framing attacks, code injection attacks, and Cross-Site Request Forgery (CSRF).

Testing Content-Security-Policy

Testing the CSP involves examining the CSP meta element Content-Security-Policy HTTP response header in a proxy tool. Some insecure configurations to investigate include:

  • The unsafe-eval directive that allows the use of eval() in the application.
  • Any unsafe-inline event handlers that may lead to the injection of malicious content into the webserver.
  • Any resources that can be loaded from any origin using the wildcard (*) source.
  • Using a wildcard (*) source for the frame-ancestors directive enabling framing for all origins.
  • Ensuring that a strict policy is applied for business-critical applications.

The security researcher can also use tools such as DAST Essentials to check the strength of their security policies.

CSP header examples

A few sample HTTP headers include:

Restricting content to the site origin

To ensure all content comes from the site origin, the web developer/administrator uses the Default-Src directive:

Content-Security-Policy: default-src 'self'

Enabling images from any origin

CSP allows for the specification of multiple policies for a resource by separating them using semicolons. For example, the developer can set user content to include images from any origin, restrict audio/video and load external scripts from a specific trusted server as shown:

Content-Security-Policy: default-src 'self'; img-src *; media-src darwin1.com darwin2.com; script-src darwincripts.example.com

Ensuring all content is loaded using TLS

Developers can prevent adversaries from eavesdropping on client requests by ensuring all website content loads using TLS. It is achieved using the security policy below:

Content-Security-Policy: default-src https://darwin.site.com

This policy ensures that the server only allows access to documents loaded through the single-origin https:darwin.site.com over HTTPS.