Chromium Security: Site Isolation
chromium.org
chromium.org
To enable, use chrome://flags#enable-site-per-process
I'm not saying "site per process" is bad thing. Of course it can help to prevent some kind of attacks, just not these new cpu related.
Site isolation mitigates variant 1 of Spectre, which allows same-process reads.
It doesn't protect against variant 2 of Spectre, which could allow cross-process reads. While this is believed to be much harder to exploit than the first variant, there are several mitigations in development:
- Reduce the reliability of timing gadgets from JS
- Compiler defenses like LLVM's -mretpoline
- Intel's IBRS microcode update
As you mentioned, site isolation also won't help against Meltdown, which allows disclosure of kernel memory: this requires the kernel page table isolation patches.
- If you have an AMD CPU or run a Kernel with KPTI you are protected from Meltdown.
- If you have an AMD CPU or compile the browser with retpoline you are protected from the second variant of Spectre (branch misprediction).
- If you have site isolation you are protected from the first variant of Spectre (bound check).
Thus, as it stands (and my understanding is that more variants will inevitably be found), this feature alone mitigates the known attacks on AMD hardware.
Of course the real mitigation is to air-gap your computer and only run code you have proven to be secure by hand. But Google can never suggest that. /s
AMD is pushing microcode updates to close those holes, too.
"Variant Two
Branch Target Injection
Differences in AMD architecture mean there is a near zero risk of exploitation of this variant. Vulnerability to Variant 2 has not been demonstrated on AMD processors to date."
And although Project Zero had multiple AMD test machines they did not make any claims that AMD was also vulnerable to variant 2. Can you link to any PoC that has gotten variant 2 to work on AMD?
Once you have support for out of process iframes, you can lock down each process so that it doesn't have access to data for sites other than the one it was created to render documents for. That lockdown is what can prevent Spectre variant 1 from being used to steal data cross-site: the data is no longer in the process to steal.
Site per process helps against the other two variants which are about reading other process memory and have been demonstrated to be able to extract passwords from firefox browser memory (which has been fixed in the newest version)
The highly experimental language dates back for several years (I think there's been a patch to revise the wording). This mode is already launched for all extension content since mid 2017, so it is well exercised. I no longer consider it highly experimental. The things that we know don't with are listed on the originally linked page; memory usage surprised us by not being a worse regression than it was.
The TLDR of site isolation is that the same origin policy is enforced at a process boundary, rather than relying on the rendering engine to keep the JavaScript contexts within a process (say, evil.com and its bank.com iframe) from accessing each other's memory. With site isolation on, we put the subframe in it's own process; the parent process can't, for example, read cookies for the child process's origin.
This relates to the novel CPU vulnerabilities because, to quote the blog post today, "The primary ramification of Variant 1 is that it is difficult for a system to run untrusted code within a process and restrict what memory within the process the untrusted code can access."
Site isolation was designed as a defense in depth against the type of renderer compromise that would give an attacker arbitrary code execution in the renderer process. Variant 1 gives attackers something weaker than that, so the protection works.
Wish I had a better timeline to share, but with stuff like printing not working properly, it's not an easy decision to just flip it on for everyone.
Wait, it breaks printing? In what situations?
Edit: Just saw Known Issues on the page.
From my understanding, the mentioned MIME types were already protected by CORS (e.g., you can load a non-allowed cross-origin HTML document in an iframe, but then you won't get scripting access to it; If you try to get it directly via fetch or XHR, you cannot access the result)
So what exactly changes for consumers of such documents?
Your intuitions are mostly right, in that the document blocking logic is related to CORS protection. In fact, when the document blocker sees a valid access-control-allow-origin header in a response, that's sufficient to allow it through.
However, there are a couple reasons though why CORS alone is not enough. First, the CORS checks (the ones that generate console warnings when they fail) are done inside the renderer process -- meaning some of the response data has already arrived in the process, and may be available for exfiltration by an agent able to read that process's memory.
Secondly, CORS only applies to cors-enabled requests (e.g. XHR and fetch). Our goal is to prevent, say, the HTML of your bank account details page or a similarly sensitive JSON-based API from arriving in any renderer process other than one dedicated to rendering pages for your bank's site. An attacker could point a script tag at the target resource -- script tags by default aren't required to go through the CORS dance (as an aside, <script crossorigin> exists, but I'm not entirely sure why). Since the attackers goal is just to cause the response to wind up in its renderer process memory, the attack still succeeds even if the JSON or HTML doesn't successfully execute as valid javascript.
So we need something stronger, which runs outside the renderer process. The idea is to look for responses that would necessarily result in an error in the context of any legitimate cross-origin use case (other than fetch/xhr, where CORS dictates what's legal). We need to block HTML, but allow stylesheets, images, and scripts. The blocking logic is really based on the substance of the http response, rather than what the renderer says it's to be used for, since the renderer is untrusted in this scenario.
JSON is a particular headache, since a subset of JSON is also valid javascript (dicts are syntax errors, but lists are we aren't), and as a result, JSON in the wild is often prefixed, and thus doesn't sniff as JSON. JSON also is often served with a JavaScript mime type.
An important takeaway for website authors is to serve any JSON or HTML with the appropriate mime type and the nosniff header.
Thanks for the answer and for the awesome work in general!
Huh? These are two _very_ different situations. Not setting `Access-Control-Allow-Origin` would mean that no third party site can read data from your domain. Setting it to `*` would do the exact opposite, allowing any site to read data on the page.
It's also unclear to me how this relates to Spectre and Meltdown.
> This protection is made possible by the following changes in Chrome's behavior:
> […]
> - Cross-site "documents" (specifically HTML, XML, and JSON files) are not delivered to a web page's process unless the server says it should be allowed (using CORS).
I understand it to mean that the tab's process used to hold code that verified the CORS header, and that the verification is now out-of-process.
[0]: http://www.chromium.org/Home/chromium-security/site-isolatio...
Enabling site per process in chrome will give your users some protection of their data on your site, but only if your mime types are already correct. See the probably linked document for recommended headers.
Back in the day (Around when I ported chrome to Linux for a time context) I wrote up a spec and implemented a browser that did site data compartmentalization. Data leaks from cookies, history and especially cache were not possible because the data just wasn't there to be leaked. It was a pretty cool design that along with per site settings and split view search was definitely ahead of its time. Alas I was forbidden from working on it by my employer at the time and have been watching for some of the features to appear in other browsers since.
https://benjamin-meyer.blogspot.com/2009/08/next-generation-...
You can see your example in action by enabling site isolation, visiting a page with a FB like button, and opening Chrome's task manager. You can even kill the subframe process, and it shouldn't take down the whole tab.
SNI was created so that multiple SSL-enabled websites could share the same IP address. (Perhaps because IP addresses are an undue expense for some website owners, unlike, say, chromium.org.)
Assuming the the single IP address is not "anycasted" (another undue expense), does SNI imply that multiple websites1 are in some way sharing a common computer?
Could that be relevant with respect to "site isolation" in any way? Why or why not? (For example, does the server side, perhaps with multiple "tenants" sharing the same hardware, pose a risk to the client concerned about undesirable memory access?)
1 Presumably those websites are handling sensitive information hence the need for SSL.
In any case, the Site Isolation feature described here is a browser feature, unrelated to how the sites are hosted. Site Isolation provides additional isolation between different websites loaded in a user's web browser in order to limit the scope of some potential exploits: for example, to make it more difficult for malicious code hosted on example.org to access your gmail.com credentials.
The discussions about "Chrome-only" sites are absolutely acceptable, but totally off-topic here. Mozilla has also been working hard on Electrolysis to have multiple processes. That's a very big security feature that should become a must have for all browsers.
To illustrate how much complexity this brings, consider a browser feature like find-in-page. It used to work by traversing the document and descending into subdocuments synchronously. It was basically a big for loop. With the page and its iframes split across multiple processes, now we need a protocol and interprocess communication to coordinate the find operation, and assemble the matches together into a tree. The results of this async operation can arrive in any order, and you need to filter out late arriving responses for previous queries, when the user modifies the search string.
This pattern needs to be implemented, rinse and repeat, for hundreds of subsystems. It was really hard.