The Content Security Policy (CSP) is a protection standard that helps secure websites and applications against various attacks, including data injection, clickjacking, and cross-site scripting attacks. CSP implements the same-origin policy, ensuring that the browser only executes code from valid sources. Developers can use precisely-defined CSPs to eliminate common attack vectors by defining the content sources. This article explores a content security policy and how a CSP header can help prevent common vulnerabilities.
What is Content Security Policy?
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.
CSP directives fall under various categories depending on use-case and content attribute. These include:
These directives specify the locations for loading certain resource types. Fetch directives include:
- child-src: defines the whitelisted script sources 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 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 document’s base element
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
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.
Why is CSP Header Relevant in Cyber Security?
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 additional layer of application security.
CSPs enable granular control over:
- Inline script execution
- How inline styles are applied
- Dynamic code execution
Vulnerabilities You Can Prevent Using CSP
CSPs protect web applications from several vulnerabilities and attacks, including:
CSPs form the first line of defense against XSS attacks as they block the execution of malicious scripts injected by untrusted sources. 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 whitelisting resource origins, CSPs also 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’s contents can also be specified in a CSP directive. The script only runs when the actual script’s hash matches the value in the CSP directive.
The frame-ancestors ‘self’ CSP directive governs that only pages with the exact origin can frame the policy’s 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’s 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.
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 available tools such as the Crashtest Security Suite to check the strength of their security policies.
Examples of CSP Header
A few sample HTTP headers include:
Restricting content to the site’s origin
To ensure all content comes from the site’s 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 via TLS
Developers can prevent adversaries from eavesdropping on client requests by ensuring all of a website’s content is loaded 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.
How do I add CSP policies to my website?
There are two ways to load CSP onto a web page: the HTTP response header field or the HTML meta element.
The syntax for the HTTP header is similar to:
Content-Security-Policy: [directive] [resource type] e.g Content-Security-Policy: default-src https:
The syntax for the HTML meta element would be similar to:
<meta http-equiv="Content-Security-Policy" content="[directive] [resource type]"> e.g <meta http-equiv="Content-Security-Policy" content="default-src https:">
How do I simplify the implementation of CSP?
CSP is a popular standard supported by most server frameworks and web browsers. However, implementing CSP for a dynamic web project is tedious, so web administrators need a CSP manager for easier content security management. Tools such as the Crashtest Security Suite enable developers and administrators to track tags and content through automated scanning. The suite includes an inventory and context of various domains to establish a database of standard and secure content sources. The automated scanner also queries a database of block-listed servers to avoid attacks from known threat actors.