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 thebase
element of the document.
Navigation directives
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.