CSP Is Dead, Long Live CSP! On the Insecurity of Whitelists and the Future of Content Security Policy

Lukas Weichselbaum Michele Spagnuolo Sebastian Lekies Google Inc. Google Inc. Google Inc. [email protected] [email protected] [email protected] Artur Janc Google Inc. [email protected]

ABSTRACT 1. INTRODUCTION Content Security Policy is a web platform mechanism de- Cross-site scripting – the ability to inject attacker-con- signed to mitigate cross-site scripting (XSS), the top security trolled scripts into the context of a web application – is vulnerability in modern web applications [24]. In this paper, arguably the most notorious web vulnerability. Since the we take a closer look at the practical benefits of adopting first formal reference to XSS in a CERT advisory in 2000 CSP and identify significant flaws in real-world deployments [6], generations of researchers and practitioners have inves- that result in bypasses in 94.72% of all distinct policies. tigated ways to detect [18, 21, 29, 35], prevent [22, 25, 34] We base our Internet-wide analysis on a search engine cor- and mitigate [4, 23, 28, 33] the issue. Despite these efforts, pus of approximately 100 billion pages from over 1 billion XSS is still one of the most prevalent security issues on the hostnames; the result covers CSP deployments on 1,680,867 web [24, 30, 37], and new variations are constantly being hosts with 26,011 unique CSP policies – the most compre- discovered as the web evolves [5, 13, 14, 20]. hensive study to date. We introduce the security-relevant Today, Content Security Policy [31] is one of the most aspects of the CSP specification and provide an in-depth promising countermeasures against XSS. CSP is a declara- analysis of its threat model, focusing on XSS protections. tive policy mechanism that allows web application develop- We identify three common classes of CSP bypasses and ex- ers to define which client-side resources can be loaded and plain how they subvert the security of a policy. executed by the browser. By disallowing inline scripts and We then turn to a quantitative analysis of policies de- allowing only trusted domains as a source of external scripts, ployed on the Internet in order to understand their secu- CSP aims to restrict a site’s capability to execute malicious rity benefits. We observe that 14 out of the 15 domains client-side code. Hence, even when an attacker is capable of most commonly whitelisted for loading scripts contain un- finding an XSS vulnerability, CSP aims to keep the appli- safe endpoints; as a consequence, 75.81% of distinct policies cation safe by preventing the exploitation of the bug – the use script whitelists that allow attackers to bypass CSP. In attacker should not be capable of loading malicious code total, we find that 94.68% of policies that attempt to limit without controlling a trusted host. script execution are ineffective, and that 99.34% of hosts In this paper, we present the results of the first in-depth with CSP use policies that offer no benefit against XSS. analysis of the security of CSP deployments across the web. Finally, we propose the ’strict-dynamic’ keyword, an In order to do so, we first investigate the protective capabil- addition to the specification that facilitates the creation of ities of CSP by reviewing its threat model, analyzing possi- policies based on cryptographic nonces, without relying on ble configuration pitfalls and enumerating little-known tech- domain whitelists. We discuss our experience deploying such niques that allow attackers to bypass its protections. a nonce-based policy in a complex application and provide We follow with a large-scale empirical study using real- guidance to web authors for improving their policies. world CSP policies extracted from the Google search in- dex. Based on this data set, we find that currently at Keywords least 1,680,000 Internet hosts deploy a CSP policy. Af- ter normalizing and deduplicating our data set, we identify Content Security Policy; Cross-Site Scripting; Web Security 26,011 unique CSP policies, out of which 94.72% are triv- ially bypassable – an attacker can use automated methods to find endpoints that allow the subversion of CSP protec- tions. Even though in many cases considerable effort was spent in deploying CSP, 90.63% of current policies contain Permission to make digital or hard copies of part or all of this work for personal or configurations that immediately remove any XSS protection, classroom use is granted without fee provided that copies are not made or distributed by allowing the execution of inline scripts or the loading of for profit or commercial advantage and that copies bear this notice and the full citation on the first page. Copyrights for third-party components of this work must be honored. scripts from arbitrary external hosts. Only 9.37% of the For all other uses, contact the owner/author(s). policies in our data set have stricter configurations and can CCS’16 October 24-28, 2016, Vienna, Austria potentially protect against XSS. However, we find that at © 2016 Copyright held by the owner/author(s). least 51.05% of such policies are still bypassable, due the ACM ISBN 978-1-4503-4139-4/16/10. presence of subtle policy misconfigurations or origins with DOI: http://dx.doi.org/10.1145/2976749.2978363 unsafe endpoints in the script-src whitelist. Based on the results of our study, we conclude that main- 3.2, and explain our methodology in 3.3, before we present taining a secure whitelist for a complex application is infea- the results and our analysis in 3.4. Based on the results of sible in practice; hence, we propose changes to the way CSP this study, we then propose a way to improve CSP in Section is used. We suggest that the model of designating trust 4. Finally, we present related work in Section 5, before we by specifying URL whitelists from which scripts can exe- conclude in Section 6. cute should be replaced with an approach based on nonces and hashes [3], already defined by the CSP specification and 2. CONTENT SECURITY POLICY available in major browser implementations. In a nonce-based policy, instead of whitelisting hosts and 2.1 Overview domains for script execution, the application defines a single- The Content Security Policy (CSP) is a declarative mech- use, unguessable token (nonce) delivered both in the CSP anism that allows web authors to specify a number of se- policy and as an HTML attribute of legitimate, application- curity restrictions on their applications, to be enforced by controlled scripts. The user agent allows the execution only supporting user agents. of those scripts whose nonce matches the value specified in CSP is intended as “a tool which developers can use to the policy; an attacker who can inject markup into a vul- lock down their applications in various ways, mitigating the nerable page does not know the nonce value, and is thus risk of content-injection vulnerabilities (. . . ) and reducing not able to execute malicious scripts. In order to ease the the privilege with which their applications execute.” [3] adoption process of this nonce-based approach, we present CSP is evolving quickly: the version currently undergoing a new CSP source expression for ’script-src’, provision- specification is CSP3, and the standard is unevenly imple- ally called ’strict-dynamic’. With ’strict-dynamic’, dy- mented by user agents. For example, Chromium has full namically generated scripts implicitly inherit the nonce from CSP2 support and implements most of the working draft the trusted script that created them. This way, already- of CSP3, in some cases behind experimental runtime flags, executing, legitimate scripts can easily add new scripts to while Mozilla and WebKit-based browsers just re- the DOM without extensive application changes. However, cently obtained full CSP2 support [8]. When discussing the an attacker who finds an XSS bug, not knowing the correct details of CSP, we do not focus on any particular revision nonce, is not able to abuse this functionality because they of the standard, but instead attempt to provide a broad are prevented from executing scripts in the first place. overview across implementations and versions [31]. In order to prove the feasibility of this approach, we present A CSP policy is delivered in the Content-Security-Policy a real-world case study of adopting a nonce-based policy in HTTP response header or in a element. The func- a popular application. tionality of CSP can be divided into three categories: Our contributions can be summarized as follows: Resource loading restrictions. The most well-known • We present the results of the first in-depth analysis and commonly used aspect of CSP is limiting the ability to of the CSP security model, analyzing the protections load various subresources to a set of origins allowed by the against web bugs provided by the standard. We iden- developer, known as a source list. Commonly used direc- tify common policy misconfigurations and present three tives are script-src, style-src, img-src, and the catch- classes of CSP bypasses that disable the protective ca- all default-src; a full list of directives regulating resources pabilities of a policy. is shown in Table 1. As a special case, several additional configuration options are available for the script-src and • We conduct a large-scale empirical study of the bene- style-src directives; these allow more fine-grained control fits of real-world CSP deployments by extracting poli- over scripts and stylesheets and are discussed below. cies from the Google search index. Based on a corpus of approximately 106 billion pages, of which 3.9 bil- Auxiliary URL-based restrictions. Certain classes of lion are protected with CSP, we identify 26,011 unique attacks cannot be prevented by policing fetched sub-resources, policies. We find that at least 94.72% of these poli- but similarly require a concept of trusted origins with which cies are ineffective at mitigating XSS, due to policy the document can interact. A common example is the - misconfigurations and insecure whitelist entries. ancestors directive, which defines the origins that are al- lowed to frame a document in order to prevent clickjack- • Based on our findings, we propose a change to how ing [10]. Similarly, base-uri and form-action define which Content Security Policy is deployed in practice: in- URLs can be targets of and stead of whitelisting, we advocate for a nonce-based elements in order to prevent some post-XSS attacks [38]. approach. To further this approach, we present ’strict- dynamic’, a new feature of the CSP3 specification cur- Miscellaneous confinement and hardening options. rently implemented in the Chromium browser. We Due to the lack of other common mechanisms for enabling discuss the benefits of this approach and present a security restrictions in web applications, CSP has become case study of deploying a policy based on nonces and the home for several loosely fitting security features. This in- strict-dynamic in a popular web application. cludes the block-all-mixed-content and upgrade-insecure- requests keywords, which prevent mixed content bugs and The rest of this paper has the following structure: in Sec- improve HTTPS support; plugin-types, which restricts al- tion 2, we provide an in-depth introduction to CSP. Thereby, lowed plugin formats; and sandbox, which mirrors the secu- we cover the technical foundations in 2.1, the CSP threat rity features of HTML5 sandbox frames. model and common security pitfalls when designing a policy In order to make web applications compatible with a Con- in 2.2 and 2.3. Subsequently, we present the result of our tent Security Policy useful against XSS, web authors often empirical study in Section 3. In order to do so, we first out- have to refactor the HTML markup generated by the appli- line our research questions in 3.1, introduce our data set in cation logic, as well as by frameworks and templating sys- Directive Controlled resource type out(), setInterval(), and the Function constructor. default-src All resources (fallback) Otherwise, these APIs are blocked by a policy with a script-src Scripts script-src directive. style-src Stylesheets img-src Images 3.A CSP nonce allows the policy to specify a one-time media-src Media (audio, video) value that acts as an authorization token for scripts font-src Fonts (script-src ’nonce-random-value’). Any script on frame-src Documents (frames) the page with the correct nonce="random-value" at- object-src Plug-in formats (object, embed) tribute will be allowed to execute. child-src Documents (frames), [Shared]Workers worker-src [Shared]Workers 4.A CSP hash allows the developer to list cryptographic manifest-src Manifests hashes of expected scripts within the page (script- src ’sha256-nGA...’). Any inline script whose digest Table 1: CSP directives and controlled resources matches the value supplied in the policy will be allowed to execute. tems. In particular, inline scripts, the usage of eval and Nonces and hashes can similarly be used with the style- equivalent constructs, inline event handlers and : src directive to allow the loading of inline stylesheets and URIs must be avoided or refactored with CSP-friendly al- external CSS whitelisted via a nonce value. ternatives. In addition to the default behavior of enforcing policy re- Content-Security-Policy: script-src ’nonce-BPNLMA4’ strictions, CSP can be configured in Report-Only mode, in ’sha256-OPc+f+ieuYDM...’ object-src ’none’; which violations are recorded but not enforced. In both cases, the report-uri directive can be used to send viola- Listing 2: Locked down policy using a nonce and a hash tion reports to inform the application’s owner of incompat- ible markup. 2.2 The threat model of CSP In order for CSP to offer a security benefit, it must pre- Content-Security-Policy: script-src ’self’; style-src vent attackers from exploiting flaws that would otherwise cdn.example.org third-party.org; child-src : enable malicious actions against the application’s users. In its current form, CSP offers protections from three types of Listing 1: Example of a traditional CSP policy vulnerabilities [3]:

2.1.1 Source lists • XSS: the ability to inject and execute untrusted scripts CSP source lists (commonly known as whitelists) have in a vulnerable application (protected with the script- been a core part of CSP and are the traditional way to src and object-src directives) specify trust relationships. For example, as shown in List- ing 1, an application might choose to trust only its hosting • : forcing users to take unwanted actions domain for loading scripts, but allow fonts or images from in an affected application by overlaying hidden frames cdn.example.org and third-party.org, and require frames on attacker-controlled pages (protected by restricting to be loaded over HTTPS, while enforcing no restrictions on framing with frame-ancestors) other resource types. For any directive, the whitelist can be composed of host- • Mixed content: Accidentally loading resources from in- names (example.org, example.com), possibly including the secure protocols on pages delivered over HTTPS (pro- * wildcard to extend trust to all subdomains (*.example.org); tected with the upgrade-insecure-requests and block- schemes (https:, data:); and the special keywords ’self’, all-mixed-content keywords and by restricting the denoting the origin of the current document, and ’none’, loading of scripts and sensitive resources to https:). enforcing an empty source list and prohibiting the loading It follows that only a small subset of CSP directives are of any resources whatsoever. useful for XSS protection. Furthermore, the ability to exe- Starting with CSP2, authors also have the option to spec- cute malicious scripts in the context of an application sub- ify paths in their whitelists (example.org/resources/js/). verts the protections offered by all other directives, as dis- Interestingly, path-based restrictions cannot be relied on to cussed in Section 2.2.2. limit the location from which resources can be loaded; a broader discussion of this issue is provided in Section 2.3.4. 2.2.1 Benefits of adopting CSP 2.1.2 Restrictions on script execution Since some popular user agents do not yet support CSP or offer only partial support[8], CSP should only be used Because of the significance of scripting in modern web as a defense-in-depth to hinder attack attempts in case the applications, the script-src directive provides several key- primary security mechanism has failed. Accordingly, appli- words to allow more granular control over script execution: cations using CSP must also employ traditional protection 1. unsafe-inline allows the execution of inline fully prevents script execution. In general, non-script direc- tives might serve as a defense against some post-XSS [38] or /* API response */ “scriptless” [13] attacks, such as exfiltrating data by hijack- alert(document.domain);//{"var": "data", ...}); ing form URIs, or phishing by spoofing the page UI using Listing 6: Loading JSONP data attacker-controlled styles, but they improve security only if CSP is already effective as a protection against XSS. Unfortunately, if a domain whitelisted in the policy con- To achieve the primary goal of preventing unwanted script tains a JSONP interface, an attacker can use it to execute execution, a policy must meet three requirements: arbitrary JavaScript functions in the context of a vulner- able page by loading the endpoint as a strained script execution. If the character set is restricted and thus only the function name is controllable, they can use techniques such as SOME [12] which are often qualitatively equivalent to full, unconstrained XSS. 2.3.2 Reflection or symbolic execution Listing 3: CSP bypass due to missing directives Restrictions on CSP script execution can be (often acci- • The script-src source list cannot contain the unsafe- dentally) circumvented by a cooperating script in a whitelisted inline keyword (unless accompanied by a nonce) or origin. For example, a script can use reflection to look up allow data: URIs. and invoke a function in the global scope, as depicted in Listing 7.

// Can be used to invoke window.* functions with // arbitrary arguments via markup such as: Listing 4: Bypass for unsafe-inline and data: URIs // • The script-src and object-src source lists cannot var array= contain any endpoints that allow an attacker to con- document.getElementById(’cmd’).value.split(’,’); trol security-relevant parts of the response or contain window[array[0]].apply(this, array.slice(1)); unsafe libraries. Listing 7: JavaScript reflection gadget Such JavaScript gadgets would normally not compromise

security, because their arguments are under the control of {{ executeEvilCodeInUnsafeSandbox() }}
the developer whose page loads the script. A problem arises when such scripts obtain data by inspecting the DOM, which Listing 5: XSS CSP whitelist bypasses can be partly attacker-controlled if the application has a If any of these conditions is not met, the policy is not effec- markup-injection bug – an attacker can then execute ar- tive at preventing script execution and consequently offers bitrary functions, possibly with unconstrained arguments, no protection from content-injection attacks. bypassing CSP. A practical example is the behavior of the popular An- 2.3.4 Path restrictions as a security mechanism gularJS library, which allows the creation of single-page ap- To address issues about insufficient granularity of domain- plications with powerful templating syntax and client-side based source lists, CSP2 introduced the ability to constrain template evaluation (Listing 8). whitelists to specific paths on a given domain (e.g. exam- ple.org/foo/bar). Developers now have the option to des-
{{ 1000 - 1 }}
ignate specific directories on a trusted domain for loading scripts and other resources. Listing 8: Bypassing CSP by loading AngularJS Unfortunately, as a result of a privacy concern related to To achieve its goal, AngularJS parses templates in des- the handling of cross-origin redirects [15], this restriction has ignated parts of the page and executes them. The ability been relaxed. If a source list entry contains a redirector (an to control templates parsed by Angular can be considered endpoint returning a 30x response that points to another equivalent to executing arbitrary JavaScript. By default, location), that redirector can be used to successfully load Angular uses the eval() function to evalute sandbox ex- resources from whitelisted origins even if they do not match pressions, which is prohibited by CSP policies without the the path allowed in the policy. unsafe-eval keyword. However, Angular also ships with a “CSP compatibility mode” (ng-csp), in which expressions Content-Security-Policy: script-src example.org are evaluated by performing symbolic execution, making it partially-trusted.org/foo/bar.js possible to call arbitrary JavaScript code despite CSP. As a consequence, an attacker who can load the Angular // Allows loading of untrusted resources via: library from a domain whitelisted in the CSP can use it as At the same time, CSP already offers more granular meth- ods of granting trust to scripts: cryptographic nonces and hashes. In particular, nonces allow the developer to explic- By using a nonce, scripts can be whitelisted individually. itly annotate every trusted script (both inline and external), Even if an attacker is capable of finding an XSS, the nonce while prohibiting attacker-injected scripts from executing. value is unpredictable, so it is not possible for the attacker In order to improve the overall security of CSPs in the to inject a valid script pointing to the JSONP endpoint. wild, we thus propose a slightly different way of writing poli- One useful feature of CSP is that it allows for the central cies. Instead of relying on whitelists, application maintain- enforcement of security decisions. A security team might, ers should apply a nonce-based protection approach. The for example, use CSP for enforcing a set of trusted hosts following listing depicts a whitelist-based CSP policy and a from which scripts are allowed to be loaded, instead of rely- script satisfying this policy: ing on the goodwill of developers to not include scripts from untrusted sites. In a single nonce-based policy, however, this Content-Security-Policy: script-src example.org is not possible; a resource is only required to adhere to either the whitelist or the nonce. Hence, adding a whitelist to a ingly, browsers allow the enforcement of multiple policies. If two policies are specified for a page, the browser ensures that Unfortunately, the whitelist of this policy contains an un- a resource adheres to both policies. Hence, this feature can safe host and thus the depicted policy is insecure. The at- be used to get the benefits of both worlds: one nonce-based tacker could abuse the JSONP endpoint by injecting a script policy can be used to whitelist individual scripts, while a with the following URL: https://example.org/script? second whitelist-based policy can be used to centrally en- callback=malicious_code. force security decisions. Two policies can be transferred to the client in the same HTTP response header by separating them with a comma: Count Percentage script-src value JSONP Bypass AngularJS Bypass Bypassable 8825 33.93% www.google-analytics.com yes, if unsafe-eval no yes, if unsafe-eval 7201 27.68% *.googleapis.com yes yes yes 6307 24.25% *.google-analytics.com yes, if unsafe-eval no yes, if unsafe-eval 5817 22.36% *.google.com yes no yes 5475 21.05% *.yandex.ru yes no yes 5146 19.78% *.gstatic.com no yes yes 5076 19.51% vk.com yes no yes 4728 18.18% mc.yandex.ru yes no yes 4423 17.00% yandex.st no yes yes 4189 16.10% ajax.googleapis.com yes yes yes 3829 14.72% *.googlesyndication.com yes no yes 3621 13.92% *.doubleclick.net yes no yes 3617 13.91% yastatic.net no yes yes 2959 11.38% connect.facebook.net no no no 2809 10.80% www.google.com yes no yes

Table 5: Bypassability of the 15 most common whitelisted hosts in script-src

Content-Security-Policy: This mode of using CSP offers the promise of enabling nonce-based policies, in which the capability to execute scripts script-src https://example.org is controlled by the developer by setting nonces on trusted default-src https://foobar.org, scripts, and allowing trust to propagate to subscripts by set- ting ’strict-dynamic’. script-src ’nonce-random123’ As an example, a developer could set a policy similar to the following: Another problem with nonce-based policies arises, how- Content-Security-Policy: ever, when new scripts are added to the page by JavaScript: script-src ’nonce-random123’ ’strict-dynamic’; because JS libraries might not be aware of CSP and do not object-src ’none’; know the correct CSP nonce, dynamically inserted scripts would be blocked from executing by CSP, and parts of the application would fail. With such a policy, the owner would need to add nonces To address this problem and to facilitate safe policies to static