March 12th, 2021
The web platform relies on the origin as a fundamental security boundary, and browsers do a pretty good job at preventing explicit leakage of data from one origin to another. Attacks like Spectre, however, show that we still have work to do to mitigate implicit data leakage. The side-channels exploited through these attacks prove that attackers can read any data which enters a process hosting that attackers’ code. These attacks are quite practical today, and pose a real risk to users.
Our goal must be to ensure that sensitive data doesn’t unexpectedly enter an attacker’s process. Browsers shoulder a large chunk of this responsibility: Chromium’s Site Isolation can separate the sites you visit into distinct OS-level processes, cross-origin read blocking prevents attackers from loading a subset of otherwise-vulnerable cross-origin resources, and APIs that substantially increase attackers’ bandwidth (like SharedArrayBuffer) are being locked to cross-origin isolated contexts. This last mechanism, however, points in the direction of work that browsers can’t do on their own.
Web developers know their applications intimately, and can make informed decisions about each page’s and resource’s risk of exposure. To defend users’ data against exfiltration, web developers must step in, evaluate resources they host, and instruct browsers to isolate those resources accordingly. At a high-level, this defense consists of:
- Deciding when to respond to requests by examining incoming headers, paying special attention to the Origin header on the one hand, and various Sec-Fetch- prefixed headers on the other.
- Restricting attackers’ ability to load resources as a subresource by setting a cross-origin resource policy of same-origin (opening up to same-site or cross-origin only when necessary).
- Restricting attackers’ ability to frame resources as a document by opting into framing protections via X-Frame-Options: SAMEORIGIN or CSP’s more granular frame-ancestors directive: for example, frame-ancestors ‘self’ https://trusted.embedder.
- Restricting attackers’ ability to reference your application’s windows by setting a cross-origin opener policy. In the best case, you can default to a restrictive same-origin value, opening up to same-origin-allow-popups or unsafe-none only if necessary.
- Preventing MIME-type confusion attacks and increasing the robustness of passive defenses like cross-origin read blocking by setting correct Content-Type headers, and globally asserting X-Content-Type-Options: nosniff.
Together, these various defenses help all browsers offer some degree of process-level protection for users’ data, whether or not Site Isolation is available.
To find out more about employing these defenses, check out Post-Spectre Web Development. It includes practical examples that explain in more detail how the security primitives discussed above apply to resources you might have on your sites.
These are useful steps you can take today to protect your origin against implicit data leaks. Looking forward, we hope to help the web shift to safer defaults which protect users against these attacks without requiring developer action.