What is Content Security Policy (CSP)?
Content security policy (CSP) is a capability defined by the W3C to limit the threat of cross-site scripting (XSS) attacks. Implemented as part of the web standards, CSP directs the browser to enforce certain client-side policies and restrict what scripts and resources it can load for a given website. For example, the script-src directive in CSP can specify an allowlist of known domains from which inline scripts can be loaded. This can thwart an attack involving a malicious Shadow Code injection from an unauthorized domain.
CSP can also restrict network communication to specific domains using the connect-src directive. This can prevent XHR requests to malicious domains that might be used to exfiltrate stolen data. CSP can be sent to the browser either as an HTML meta tag or as a content-security-policy header. When there are multiple content security policies specified, for example using a meta tag and a content-security-policy header, the browser will use the most restrictive directives.
CSP is typically configured on the web server or injected via a content delivery network (CDN). The website administrator must ensure that the CSP directives include all required domains and must update them regularly. Failure to do so may result in websites with broken functionality and a poor user experience.
How Does a Content Security Policy Work?
Content security policy (CSP) consists of a set of directives sent to the browser either as a content-security-policy header sent as part of the HTTP response header, or an HTML meta tag included inline on the page. When a browser receives these directives, it inspects every resource and script that the page requests and checks to ensure that the origin domain is part of the allowlist. If not, it blocks the resource from loading.
CSP also supports a report-only mode which uses the content-security-policy-report-only header. In this mode, the browser inspects resources and scripts against the allowlist but does not block them. Instead, policy violations are simply reported to a server specified in the report-uri directive. This mode is not supported using HTML meta tags and the directives must be sent in the HTTP header.
These are the directives supported as part of CSP.
|default-src||Specifies the default policy for fetching all types of resources. This serves as a fallback when there is no explicit directive for a resource type.|
|object-src||Specifies allowed sources for plugins, e.g.|
|img-src||Specifies allowed sources for images.|
|media-src||Specifies allowed sources for media.|
|style-src||Specifies allowed sources for stylesheets or CSS.|
|frame-src||Specifies allowed sources for loading frames.|
|font-src||Specifies allowed sources for loading fonts.|
|connect-src||Specifies allowed domains for XHR, WebSocket, fetch(), or EventSource.|
|report-uri||Specifies a URI where the browser must post reports of content security policy violations. This can also be used in the content-security-policy-report-only header which reports violations but does not block the resources from loading.|
|sandbox (optional)||Loads the page in a sandbox that applies the same-origin policy and prevents popups, plugins and script execution, similar to the iframe sandbox. This directive can include values that selectively allow certain exceptions.|
|report-uri||Specifies a URI where reports of policy violations must be posted.|
The directives that end in ‘-src’ support values known as the source list. These could be domain names, wildcards or specific values defined in the CSP specification such as ‘self’, ‘none’, ‘unsafe-inline’ or ‘unsafe-eval’.
CSP is supported by most common browsers including Google Chrome, Safari, Firefox and Edge.
Using a Content Security Policy (CSP)
The content security policy header is included as part of the HTTP response header. It consists of a set of directives followed by source lists.
The simplest example of CSP is one that only allows first-party resources.
Content-Security-Policy: default-src 'self';
Here is another example of a longer, more complex CSP header.
Content-Security-Policy: default-src 'self'; img-src *.istockphotos.com; script-src ‘self’ myscripts.example.com report-uri http://my-report-uri.com
This CSP specifies domains for loading images and scripts, and a report-uri domain. All other resources must be loaded from ‘self’, which is the domain serving this page.
Here is another example of a report-only CSP header.
Content-Security-Policy-Report-Only: default-src 'self' report-uri http://my-report-uri.com
This CSP header will report all ‘violations’, i.e. any resources not loaded as first-party, since the default-src directive only allows ‘self’. However this policy will not prevent third-party resources from being loaded. This is a great way to test a CSP without risking website functionality.
Only 8% of organizations have insight into Shadow Code. Read the Osterman Research report to explore the hidden risk to your website.
Content Security Policy and Shadow Code
Content security policy is a useful tool in the fight against unauthorized Shadow Code that plagues web applications. Shadow Code typically gets included into a web page through open source libraries or third-party scripts used on the site. Introduced without formal approvals or security validation, Shadow Code runs on the client-side browser and cannot be seen or controlled using server-side security tools. Since it has full access to the web page, it can be used to launch client-side attacks such as digital skimming, formjacking and Magecart, leading to data breaches or compliance penalties.
CSP script-src directive can be used to restrict the domains from where scripts can be loaded. This ensures that scripts are only loaded from known good domains, reducing the risk of Shadow Code injections on the website. Additionally, the connect-src directive can be used to restrict network communication with unknown domains, which can stop a malicious script from communicating with its command and control (C2) server and thus limit its ability to cause harm.
What Are the Limitations of CSP?
While content security policy is a useful tool in the fight against XSS, digital skimming and Magecart attacks, it is not without its limitations.
- Browser support: Content security policy is almost universally supported by most browsers, with one notable exception – Internet Explorer (IE) – which only partially supports CSP.
- Browser extensions: Some browser extensions may completely disable CSP in the browser settings. This would render all the CSP directives ineffective.
- First-party attacks: Hackers can gain access to one of the allowed hosts or ‘self’ in the CSP and host the malicious scripts there. CSP will not protect against first-party attacks.
- Version management: CSP directives require an up-to-date source list that includes all the domains required to load all the scripts that power the website. With third-party scripts, this is very difficult to manage since vendors might frequently change how the script is delivered. Additionally, with the high pace of innovation in some industries such as e-commerce, the website itself might change frequently, requiring frequent updates to the CSP.
- Limited directives: CSP directives are limited in what they can control. For example, they cannot prevent a script from modifying the document object model (DOM), which could be used to insert fake checkout buttons or hijack users to a malicious domain. Also, CSP cannot prevent a script from writing to local storage, which could be used in a multi-phase attack.
Alternatives to CSP
- Easy to integrate: Solutions should not require a major change to the website architecture or content delivery network.
- Easy to manage: Security policies often fall behind if they are difficult to maintain. Eventually such policies become ineffective as they are forced into fail-open configurations.
- Performant: Solutions should not impose performance penalties that run the risk of degrading user experience.
- Universally supported: Solutions should be uniformly supported across a wide variety of browsers and platforms. Exceptions create holes in your security defenses that attackers can exploit.
CSP is an attractive solution since it is easy to integrate, almost universally supported and does not impose any performance penalties. On the flip side, it can be difficult to manage in an agile environment where over 70% of the scripts are external.
Other solutions for web application security include:
- Sandboxing: This approach involves running third-party services within controlled sandboxes in the web application. These vendor-specific sandbox technologies can control what third-party scripts are allowed to do, thus providing an enforcement point over external code. Sandboxing technologies do impose a performance penalty since they leverage a client-side or server-side proxy. Also, they require changes to the website architecture and require frequent policy updates to accommodate changes in third-party scripts.