Introduction
Over the past decade, web applications have become feature-rich and ubiquitous, with services like WhatsApp Web, Proton Mail, online password managers, encrypted file-sharing services, crypto wallets, and encrypted collaboration suites in increasingly widespread use.
But in-browser encryption, on which all such web services rely, still depends on server trust: If the server sends you malicious code, it’s game over. To achieve secure browser-based cryptography, there must be some assurance that the code being served to users has not been tampered with.
For a future version of SecureDrop, the issue of verifiable in-browser JavaScript (and other executable content like WebAssembly) lies on the critical implementation path. In order to provide both robust end-to-end encryption and plausible deniability for sources, SecureDrop will have to rely on browser-based encryption on the source side, since part of plausible deniability means avoiding bespoke apps or browser extensions.
In this post, we review the problem of browser-based cryptography and discuss existing attempts to address it. In a subsequent post, we will outline our work toward a solution that we hope will have applications for the wider browser security space.
Tale as old as time
The problem of relying on browser-based JavaScript for cryptography can be described succinctly: “If you don't trust the server not to keep user secrets, you can't trust them to deliver security code.” This has been a known problem for at least a decade.
As Micah Lee put it in 2015 when discussing the use of email services like Proton Mail, which relies on browser-based JavaScript for encryption:
You have to completely trust that the server is not compromised because every single time you load the page, you download a new copy of the JavaScript. They could just wait until you load the page and give you a malicious version of the JavaScript. This would be much more difficult to do if it was a browser add-on or a native program you install because then if they wanted to make their client malicious, they would have to add a backdoor and make it malicious for everyone, and everybody would have evidence of that backdoor.
But as we’ve mentioned, a SecureDrop browser extension or native app would be pretty compelling evidence that someone was interested in becoming a journalistic source. So, for situations in which browser-based end-to-end encryption is to be meaningfully trusted, there’s still a missing piece.
And yet, it persists
Many aspects of web and browser security have improved in the years since this problem was originally described, including the adoption of widespread in-transit encryption and the availability of various mitigations against web and browser security issues. However, without a mechanism that stops attackers from actively interfering with code being served, even those features do not solve the underlying problem.
Two features that are commonly referenced in the context of potential solutions are subresource integrity and the Web Crypto API.
Subresource integrity is primarily aimed at preventing a malicious Content Delivery Network from serving untrusted content to an end user. That is a problem worth mitigating, but does not address the issue of a compromised server generating correct hashes for malicious code served by the CDN. And the Web Crypto API, which provides browser-native mechanisms for performing cryptographic operations, does not provide any assurances about the code that can invoke this API.
Case studies
Malicious code being served to the browser is difficult to detect — it could be tailored to a specific user or even a particular page load, either by attackers who compromise a server or by server administrators themselves. By nature, these attacks are intended to be covert and are difficult to document, but the following case studies point to real-world scenarios with a similar root cause.
In 2018, for instance, The Verge reported on an attack against users of the cryptocurrency wallet service MyEtherWallet, in which malicious actors emptied user wallets without compromising the MyEtherWallet servers directly. In this case, attackers tampered with DNS and BGP servers to spread malicious routing information and send users to a fraudulent clone of MyEtherWallet’s platform; users who visited the fraudulent site were exposed to malicious JavaScript that compromised their wallet private keys.
While this attack also required users to click through an HTTPS certificate signature warning, it’s easy to imagine other attack scenarios (such as direct compromise of the server, or even a compromised CA) that would not have induced any such warning. In any case, the attack could have been stopped by a browser mechanism that blocked JavaScript from executing if it failed given checks for a given hostname.
A central tenet of SecureDrop has always been: Maintain control over your data. Placing trust in a third party that can access any of your data may prove problematic if your interests and theirs diverge — for example, if those parties are required by law enforcement to produce your data.
In another case in 2018, encrypted email provider Tuta (then Tutanota) was ordered by a German court to provide an account’s email content to law enforcement authorities. Then, in 2019, Tuta received a court order to develop a real-time monitoring tool that would allow law enforcement to intercept all incoming and outgoing emails from a specific account for a period of time, collecting ciphertext if the contents were end-to-end encrypted, and plaintext emails otherwise.
Tuta maintains that it has never served backdoored code to users, and has legally challenged the request to monitor user content. However, as regulations around law enforcement requests for end-to-end encrypted data are an evolving topic, note that if a provider ever were compelled to serve such code, there is no technical means by which the end user could become readily aware of changes made to the code served to them in the browser.
As an aside, Proton, another encrypted email service and a main competitor of Tuta, is in a similar position, having agreed to monitor the IP addresses of specific users following requests from law enforcement. Proton’s transparency report does not distinguish between the different types of content that it has provided in response to such requests.
Problem scope
As explained by Meißner et al. of the Institute of Distributed Systems at Germany’s Ulm University, in their 2021 paper introducing a browser code integrity prototype called Web Application Integrity Transparency, “What is missing is a concept that provides integrity validation for web applications in the browser on behalf of the user.”
There are, of course, other types of attacks that can affect browser-based applications but that don’t involve untrusted code executing in the browser, or are wider than the problem as we are prepared to scope it.
For example, well-documented cases show civil society organizations being targeted with network interference and redirected to malicious sites despite correctly typing a URL in a browser, or of compromised servers serving malicious JavaScript in a variety of contexts. But for our work and SecureDrop’s needs, our research effort is focused on defining what a code integrity mechanism would look like for a single-page web application where JavaScript is an unavoidable requirement for client-side cryptography.
Along with WAIT, mentioned above, efforts to address this problem have included the platform-specific Code Verify initiative by Meta; the Page Integrity and Webext Signed Pages browser extensions; and other proposals, including one from Proton, that suggest prioritizing the enforcement of transparency over integrity.
Conceptually related projects such as Verena and Mylar address the issue of client integrity, but their focus is on servers needing to perform computations (such as searches) over user data in an authenticated or privacy-preserving manner.
In short, there is still a need for further work in this area — due to the significant architectural changes that the proposed solutions would require of web applications, their reliance on trust-on-first-use, limitations in the range of attack vectors that are mitigated, or their privacy and usability impacts. A subsequent blog post will discuss and contrast existing proposals.
SecureDrop’s requirements are often more stringent than those of other contexts. But in this case, we believe our core requirements as outlined below encapsulate both a privacy-preserving and user-friendly set of criteria that are reasonable for a variety of web application contexts.
Core requirements
The following represents what we view as the core requirements of a code integrity system that would create a suitable environment for performing JavaScript-based cryptography, for example in the context of browser-based end-to-end encryption for SecureDrop.
- The system must fail closed. A user-facing warning is insufficient. If integrity checks against an enrolled website fail, in order to protect against malicious JavaScript that could target the browser, the JavaScript served to the browser must never be executed.
- The system can’t leak information to or rely on third parties, meaning it can’t make external destination or event-driven requests that could leak information about user activity. This implies an out-of-band information source, similar to an HSTS preload list, involved in at least some part of the process.
- The out-of-band information source must be reproducible and auditable.
- Website owners must be able to dynamically update their applications without needing a release of new out-of-band information every time the application is updated. This constraint is aimed at avoiding challenges encountered with, for example, certificate pinning.
- The system shouldn't rely on manual user intervention or new user behavior (such as manually inputting or copying keys or fingerprints).
- The system must maintain compatibility with websites that are not enrolled, and must not alter the browsing experience for the user when visiting unenrolled websites.
Additional desirable properties:
- The system should make use of existing tools and technologies.
- The system should be adoptable beyond the SecureDrop use case.
- The system shouldn’t require platforms and services to dramatically alter their existing web application architecture.
Next steps
This is an area of active research and prototyping. Now that we’ve described the problem as we see it, we will continue as we did with SecureDrop Protocol to share information about our work toward a solution with applications not just for SecureDrop, but for applications relying on browser-based cryptography in general.
If this is an area of interest for you, please stay tuned. Or, if you have any early questions or comments, feel free to email us at securedrop@freedom.press.