Posted by Stephen Röttger and Artur Janc, Information Security Engineers
Three years ago, Spectre changed the way we think about security boundaries on the web. It quickly became clear that flaws in modern processors undermined the guarantees that web browsers could make about preventing data leaks between applications. As a result, web browser vendors have been continuously collaborating on approaches intended to harden the platform at scale. Nevertheless, this class of attacks still remains a concern and requires web developers to deploy application-level mitigations.
In this post, we will share the results of Google Security Team’s research on the exploitability of Spectre against web users, and present a fast, versatile proof-of-concept (PoC) written in JavaScript which can leak information from the browser’s memory. We’ve confirmed that this proof-of-concept, or its variants, function across a variety of operating systems, processor architectures, and hardware generations.
By sharing our findings with the security community, we aim to give web application owners a better understanding of the impact Spectre vulnerabilities can have on the security of their users’ data. Finally, this post describes the protections available to web authors and best practices for enabling them in web applications, based on our experience across Google.
A bit of background
The Spectre vulnerability, disclosed to the public in January 2018, makes use of a class of processor (CPU) design vulnerabilities that allow an attacker to change the intended program control flow while the CPU is speculatively executing subsequent instructions. For example, the CPU may speculate that a length check passes, while in practice it will access out-of-bounds memory. While the CPU state is rolled back once the misprediction is noticed, this behavior leaves observable side effects which can leak data to an attacker.
In 2019, the team responsible for V8, Chrome’s JavaScript engine, published a blog post and whitepaper concluding that such attacks can’t be reliably mitigated at the software level. Instead, robust solutions to these issues require security boundaries in applications such as web browsers to be aligned with low-level primitives, for example process-based isolation.
In parallel, browser vendors and standards bodies developed security mechanisms to protect web users from these classes of attacks. This included both architectural changes which offer default protections enabled in some browser configurations (such as Site Isolation, out-of-process iframes, and Cross-Origin Read Blocking), as well as broadly applicable opt-in security features that web developers can deploy in their applications: Cross-Origin Resource Policy, Cross-Origin Opener Policy, Cross-Origin Embedder Policy, and others.
These mechanisms, while crucially important, don’t prevent the exploitation of Spectre; rather, they protect sensitive data from being present in parts of the memory from which they can be read by the attacker. To evaluate the robustness of these defenses, it’s therefore important to develop security tools that help security engineers understand the practical implications of speculative execution attacks for their applications.
Demonstrating Spectre in a web browser
Today, we’re sharing proof-of-concept (PoC) code that confirms the practicality of Spectre exploits against JavaScript engines. We use Google Chrome to demonstrate our attack, but these issues are not specific to Chrome, and we expect that other modern browsers are similarly vulnerable to this exploitation vector. We have developed an interactive demonstration of the attack available at https://leaky.page/; the code and a more detailed writeup are published on Github here.
The demonstration website can leak data at a speed of 1kB/s when running on Chrome 88 on an Intel Skylake CPU. Note that the code will likely require minor modifications to apply to other CPUs or browser versions; however, in our tests the attack was successful on several other processors, including the Apple M1 ARM CPU, without any major changes.
While experimenting, we also developed other PoCs with different properties. Some examples include:
-
A PoC which can leak 8kB/s of data at a cost of reduced stability using performance.now() as a timer with 5μs precision.
-
A PoC which leaks data at 60B/s using timers with a precision of 1ms or worse.
We chose to release the current PoC since it has a negligible setup time and works in the absence of high precision timers, such as SharedArrayBuffer.
The main building blocks of the PoC are:
-
A Spectre gadget: code that triggers attacker-controlled transient execution.
-
A side-channel: a way to observe side effects of the transient execution.
1. The gadget
For the published PoC, we implemented a simple Variant 1 gadget: a JavaScript array is speculatively accessed out of bounds after training the branch predictor that the compiler-inserted length check will succeed. This particular gadget can be mitigated at the software level; however, Chrome’s V8 team concluded that this is not the case for other gadgets: “we found that effective mitigation of some variants of Spectre, particularly variant 4, to be simply infeasible in software.”
We invite the security community to extend our research and develop code that makes use of other Spectre gadgets.
2. The side-channel
A common way to leak secret data via speculative execution is to use a cache side-channel. By observing if a certain memory location is present in the cache or not, we can infer if it has been accessed during the speculative execution. The challenge in JavaScript is to find a high resolution timer allowing to distinguish cache from memory accesses, as modern browsers have reduced the timer granularity of the performance.now() API and disabled SharedArrayBuffers in contexts without cross-origin isolation to prevent timing attacks.
Already in 2018, the V8 team shared their observation that reduced timer granularity is not sufficient to mitigate Spectre, since attackers can arbitrarily amplify timing differences. The presented amplification technique was based on reading secret data multiple times which can, however, reduce the effectiveness of the attack if the information leak is probabilistic.
In our PoC, we developed a new technique that overcomes this limitation. By abusing the behavior of the Tree-PLRU cache eviction strategy commonly found in modern CPUs, we were able to significantly amplify the cache timing with a single read of secret data. This allowed us to leak data efficiently even with low precision timers. For technical details, see the demonstration at https://leaky.page/plru.html.
While we don’t believe this particular PoC can be re-used for nefarious purposes without significant modifications, it serves as a compelling demonstration of the risks of Spectre. In particular, we hope it provides a clear signal for web application developers that they need to consider this risk in their security evaluations and take active steps to protect their sites.
Deploying web defenses against Spectre
The low-level nature of speculative execution vulnerabilities makes them difficult to fix comprehensively, as a proper patch can require changes to the firmware or hardware on the user’s device. While operating system and web browser developers have implemented important built-in protections where possible (including Site Isolation with out-of-process iframes and Cross-Origin Read Blocking in Google Chrome, or Project Fission in Firefox), the design of existing web APIs still makes it possible for data to inadvertently flow into an attacker’s process.
With this in mind, web developers should consider more robustly isolating their sites by using new security mechanisms that actively deny attackers access to cross-origin resources. These protections mitigate Spectre-style hardware attacks and common web-level cross-site leaks, but require developers to assess the threat these vulnerabilities pose to their applications and understand how to deploy them. To assist in that evaluation, Chrome’s web platform security team has published Post-Spectre Web Development and Mitigating Side-Channel Attacks with concrete advice for developers; we strongly recommend following their guidance and enabling the following protections:
-
Cross-Origin Resource Policy (CORP) and Fetch Metadata Request Headers allow developers to control which sites can embed their resources, such as images or scripts, preventing data from being delivered to an attacker-controlled browser renderer process. See resourcepolicy.fyi and web.dev/fetch-metadata.
-
Cross-Origin Opener Policy (COOP) lets developers ensure that their application window will not receive unexpected interactions from other websites, allowing the browser to isolate it in its own process. This adds an important process-level protection, particularly in browsers which don’t enable full Site Isolation; see web.dev/coop-coep.
-
Cross-Origin Embedder Policy (COEP) ensures that any authenticated resources requested by the application have explicitly opted in to being loaded. Today, to guarantee process-level isolation for highly sensitive applications in Chrome or Firefox, applications must enable both COEP and COOP; see web.dev/coop-coep.
In addition to enabling these isolation mechanisms, ensure your application also enables standard protections, such as the X-Frame-Options and X-Content-Type-Options headers, and uses SameSite cookies. Many Google applications have already deployed, or are in the process of deploying these mechanisms, providing a defense against speculative execution bugs in situations where default browser protections are insufficient.
It’s important to note that while all of the mechanisms described in this article are important and powerful security primitives, they don’t guarantee complete protection against Spectre; they require a considered deployment approach which takes behaviors specific to the given application into account. We encourage security engineers and researchers to use and contribute to our Spectre proof-of-concept to review and improve the security posture of their sites.
Tip: To help you protect your website from Spectre, the Google Security Team has created Spectroscope, a prototype Chrome extension that scans your application and finds resources which may require enabling additional defenses. Consider using it to assist with your deployments of web isolation features.