Much thought was put into the design and construction of the CSP Spec. This document describes some of the reasoning behind the specification for those interested.
Content Security Policy is intended to help web designers or server administrators specify how content interacts on their web sites. It helps mitigate and detect types of attacks such as XSS and data injection. CSP is not intended to be a main line of defense, but rather one of the many layers of security that can be employed to help secure a web site. More information about the intended use of CSP is available in the goals section.
Content Security Policy is intended to mitigate a large class of Web Application Vulnerabilities: Cross Site Scripting. Cross Site Request Forgery has also become a large scale problem in Web Application Security, though it is not a primary focus of Content Security Policy.
The main goal of Content Security Policy is to prevent malicious code from being injected into a website and executed within the context of that site. Hence, a recurring theme in CSP is to prevent the creation of script code from potentially tainted strings. It should be made clear that it is not the intent of CSP to prevent navigation to arbitrary sites, but rather to restrict the types of script, media, and other resources that may be used on a web page.
Mitigate Cross Site Scripting (XSS)
XSS exploits the client's trust of the content received from the server. Malicious script is executed by the victim's browser because the victim trusts the source of the content. Content Security Policy provides a way for server administrators to reduce or eliminate their XSS attack surface:
- Website administrators specify which domains the browser should treat as valid sources of script.
- The browser will only execute script in source files from the white-listed domains and will disregard everything else, including inline scripts and event-handling HTML attributes.
- Note: event-handling is still enabled in CSP without using HTML attributes.
A secondary goal of CSP is to help mitigate clickjacking. Good references are available which describe the threat and impact of clickjacking. Clickjacking occurs when a malicious site directs a victim's mouse click onto an unintended target in another site, generally by framing the target site's content in a transparent <iframe>.
Content Security Policy enables a site to specify which sites may embed a resource.
Base Restrictions (and XSS protection)
In order to support Content Restrictions properly, some base restrictions must be enforced on a web site:
No inline scripts will execute
Allowing inline scripts on a site opens the site up to XSS attacks that leverage inline scripts to run. Such attacks could effectively manipulate the page even though the injected script may not come from a source authorized by the content restriction policy of the site.
In order to implement a content restrictions scheme properly, inline and evaluated scripts must be disabled (see above base restrictions). This enables CSP to also be used in an XSS-blocking way.
- XSS attacks are possible because the browser has no way to differentiate between content the server intended to send and content injected by an attacker. Content Security Policy forces the separation of code from content and requires authors to be explicit about the code they intend to execute
- Common vectors for injecting script into web pages have been restricted in CSP. With CSP enabled, the bar for a successful XSS attack is raised substantially, requiring an attacker to:
- inject a <script> tag into the target document
- point this tag at a script file on a white-listed host
- control the contents of the white-listed script file
- Note: websites are still able to peform event-handling in the following ways, both of which require being used from within valid white-listed script files:
- setting the on<event> properties of an element, e.g. element.onclick = myFunc;
- using addEventListener, e.g. element.addEventListener("click", myFunc, false);
- Vulnerability types mitigated:
- Reflected XSS
- Stored XSS
- HTML attribute injection
Code will not be created from strings
Functions that create code from strings during runtime can be leveraged by an attacker who can insert malicious strings into a page. Commonly, these interpreted malicious strings have the same control over a web page as an inline script, yet are potentially more difficult to detect.
- eval and related functions make trivial the task of generating code from strings, which commonly come from untrusted sources, are loaded via insecure protocols, and can become tainted with attacker controlled data.
- Note: the common AJAX pattern in which a site makes a XMLHttpRequest to fetch JSON data is still enabled under CSP using a JSON parser or inside a browser that has native JSON support.
- Vulnerability types mitigated:
- AJAX request tampering
- Improper use of dynamic properties
data: protocol blocking
XBL is used to define the properties and behaviors of elements in HTML, XUL, and SVG documents from external files and as such is a vector for script injection. As a result, XBL should be disabled on pages that use CSP, except when it is loaded from a fundamentally trusted "chrome:" or "resource:" context.
The report-uri directive could potentially be abused to exfiltrate sensitive data like cookies or other session data. As a result, it can only be transmitted to a host that is probably controlled by the same entity as the protected content. This means that a report-uri must go to another host whose public suffix and base host are the same. For instance, a report-uri in a policy for "www.mysite.com" may refer to anything that ends with "mysite.com", so long as the scheme is the same.
Policy Delivery and Multiple Policies
HTTP headers are not guaranteed to be unique in a HTTP response; in fact, there could potentially be multiple X-Content-Security-Policy headers.
RFC 2616 says:
Multiple message-header fields with the same field-name MAY be present in a message if and only if the entire field-value for that header field is defined as a comma-separated list [i.e., #(values)]. It MUST be possible to combine the multiple header fields into one "field-name: field-value" pair, without changing the semantics of the message, by appending each subsequent field-value to the first, each separated by a comma.
As a result, we must look for multiple policies in the HTTP header (separated by commas), and figure out a combination mechanism or choice of which to honor. As the CSP Spec requires, both policies MUST be honored, so the intersection, or the most lenient policy that satisfies both policies should be used.
Why Intersect Policies?
Because the X-Content-Security-Policy header may appear multiple times in the response, it is possible they're crafted by different entities and may conflict. A decision must be made about which policy to use, or whether to combine them or not. Assuming there are two different policies present, there are five obvious ways to address this conflict:
- Ignore both. Raise error in the console. Enforce "allow none" (most secure).
Simplest and safest way to lock down when the policies conflict.
- Ignore both. Raise error in the console. Enforce "allow *" (most relaxed).
This is a fail-open policy and will keep the site from breaking if two policies conflict.
- Use the first header's policy.
- Use the second header's policy.
- Enforce the intersection of the policies.
This is the technique used by CSP. For each URI that is accepted by both policies, the new intersected policy will also accept the URI. Any request that is not accepted by both policies will be rejected by the new policy. This provides the ability for interaction between multiple policy specifications, allowing infrastructure admins to add a global policy to all sites on their network that may additionally want more restrictions. This technique allows the use of multiple headers to make a widely used policy more restrictive, but never more relaxed.
The fifth option, enforcing the intersection of the policies, is the best balance between safety and flexibility so CSP implements this conflict resolution technique. Furthermore, it is likely that those controlling the network are not always the same people who maintain or create the web application itself -- the ability to "refine" or further restrict enforced policies allows the web programmers to tighten the belt on a CSP-protected page without violating the policy set out by the network (possibly set by the sysadmins).
What about http-equiv in a meta tag?
To keep in line with the "out of band" delivery of CSP policies, HTML meta tags that provide an equivalent for the HTTP X-Content-Security-Policy header will be ignored.
Conflicting report-uri values
Report-duplication (or multiple reporting) is useful in the case where two different groups want to receive reports, but may not share access to the reports archive. Take for instance a large web company that has a separate sysadmin staff (who are also in charge of security at some level) and project teams. One project team may be interested in receiving reports about violations of their CSP, but are not interested in violations on other parts of the web site. The sysadmin team wants to record all violations from all parts of the site into a massive archive. The multiple reporting technique allows both entities to receive the reports they want without causing extra data-mining work on the part of the sysadmin team to isolate the reports that each project team may want.