Improved Process Isolation in Firefox 100
hacks.mozilla.org
hacks.mozilla.org
> For Linux users, we removed the connection from content processes to the X11 Server, which stops attackers from exploiting the unsecured X11 protocol.
It's hard to overstate how much of a benefit this is in terms of security for those on Linux. Any application with access to the X11 socket effectively has the keys to the kingdom, because it can hijack other applications, including those running at higher privileges, at will. (There have been halfhearted attempts to address this over the years, but nothing that's been effective or widely adopted.) The only real solution for desktop app security on Linux is to forbid direct access to X11 entirely, and so it's a huge deal that Firefox is now able to do this.
In general, doing this sort of thing is a monumental undertaking for large applications like Firefox. Kudos to my former colleagues for pulling it off.
They didn’t isolate all the Firefox processes from X11. Only the content processes are affected, i.e. the processes whose attack surface is rather massive.
But the content processes are still going to deliver their finished work items to the GPU process for rendering. The GPU process retains all the rights it needs, including talking to X11.
You can even run Firefox via Wayland and forward a persistent XWayland session if that's your cup of tea.
If such a user wants to run untrusted programs, he'd use a virtual machine anyway.
So, I think it's very easy to overstate the benefit, and your comment did just that.
Before X11 isolation, it can: (1) get RCE in content process; (2) send events to your GNOME Shell to open a terminal; (3) send keyboard events to the terminal to download the keylogger, start it, and add it to some config file that makes it start automatically on future logins.
After X11 isolation, it will: (1) get RCE in content process; (2) get stopped because it can't send keyboard/mouse events to other applications anymore.
I do concede that our utility functions may differ, if you actually believe it and not just inflating the importance of this issue.
Also I may have a bias in that I disable JavaScript by default, so the probability of such a risk is much lower. I tried to not make that assumption though, in judging the expected loss.
People have literally gotten killed because of this type of attack. Yes, hostile nation-states probably don't care enough about you personally, but there are people for whom this is a life-and-death matter.
The one thing that reduces the impact of this is that it's Firefox on Linux, which is a niche browser on a niche OS, but desktop Linux Firefox is a product that Mozilla officially ships, which means that it's Mozilla's responsibility to protect its users.
I assumed you talked about "those on Linux", not "those on Linux who have non-negligible probability of being targeted by hostile nation-states".
It's often difficult to step back and re-evaluate initial claims, and we sometimes choose to use tactics like zooming in on improbable contexts to justify them. But I think it's healthy to face criticism that may snap us out of it, so I'm writing this comment. But it's late now, so I will not be able to follow up anymore.
P.S. I don't have GNOME installed :)
Since I cannot reply to your other comment, I will respond here. What proportion of Firefox-Linux users do you think are victims of such RCE attacks?
In your imaginary world. Real users don't know what a VM is and expect their system to be able to run untrusted programs without exposing all of their data. Which they are able to do on most modern systems.
As I cannot reply to your reply, I will write the response here. By using Wayland, surely the direct benefit of this change to you is zero...
I don't think you actually understand what's going on here.
The untrusted programs in this case would be javascript and other exploitable things that firefox interprets every time you visit a webpage. Unless you run firefox itself under a different UID or inside of a VM you are effected by this, regardless of whether you are running other "untrusted" software or not.
Maybe you are thinking that using X11 as an attack vector requires a "bad" program running in addition to firefox? If so, that is not the case, any program that is running on X11 that can execute commands or read and write files could be used for this purpose. A terminal emulator is a pretty good example of such a program.
They have certainly misunderstood the attack. Claiming this has zero utility is effectively saying sandboxing is useless, which is just plain wrong.
Congratulations to Mozilla for getting this shipped!
For instance, if you are typing $SensitiveMessage, you would be far better off doing that in a firefox 100 textedit box in a browser tab, rather than an xterm, or emacs, or your desktop environments preferred text editor, or anything else.
I currently use "secure keyboard" in xterm but I know that has problems.
So it's only more secure if you think emacs / xterm / your text editor is real likely to be compromised
It has to make a Herculean effort because it is by far the worst possible app to be typing $SensitiveMessage in.
At least Kate or gedit probably doesn't have a second tab open running a JavaScript subprocess which is presently trying to attack you so it can cryptolocker you or empty your wallet.
FF devs are finalizing a utility process overhaul and laying the groundwork for CFI; for years, Chromium has had both with a much more thorough implementation than FF will in the near future. However, the browser space desperately needs competition so I'll take what I can get. Sigh.
I'm not sure what Firefox does, I believe they use the Chromium sandbox, and I'm way out of date on that. It used to do some filesystem setup like hardened chroots, but I would assume that's been supplanted by fs namespacing.
If you have a newer kernel (5.13 or greater), you may like to experiment with landlock. It's pretty cool and unlike FireJail, no suid required. Here's a landlock wrapper for Firefox:
https://github.com/62726164/misc/blob/main/go/landlock/firef...
I'd like to learn more about open source/free Windows and MacOS MAC tools. If you know of any, please post about your experience with them.
Edit: This Windows functionality seems similar to seccomp and pledge: https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-...
I guess that makes sense, but you'd have to be aware of it when uploading and downloading stuff (it would only work from a specific designated folder).
Ideally, a “shadow” Download folder would be accessible to the process, and its content would be mirrored one-way into the real Downloads folder. Upload should display a file chooser dialog which runs in an entirely different process, and the chosen files should be in effect copied to the process’s file handles list.
Maybe one day we'll have web browsers that don't have any C code. Nothing against C. It's a great systems language, but I'd rather my web browser not use it.
Browsing the web is probably the most dangerous thing the average computer user does.
Both browsers already do this for the processes that are exposed to the internet. The software shown here additionally does it for the entire browser (with the caveat wrt uploading/downloading that I explained, and maybe some more gotchas that aren't immediately obvious).
(You may understand this nuance, but I wanted to point it out, as it's literally what the browser sandboxes do)
Both Firefox and Chrome are primarily written in C++, not C. They do use C libraries though including libc.
This is what macOS enforces - apps live within their containers.
https://developer.apple.com/library/archive/documentation/Se...
An example of such a thing, that is related to this thread, is the X11 socket being accessible even when the directory it appears to be contained in isn't bind mounted into the flakpak sandbox's mount namespace. This is because regular file system permissions do not apply to abstract sockets (which X11 can and does listen with).
I think unsharing the network namespace would fix this, and configuring X11 to not listen with any abstract sockets might be possible, but this is just one of many examples of trivial sandbox escapes that most people would never even consider.
The best bet to isolate untrusted software is to run it under a different UID (less safe) or inside of a VM (probably very safe).
Ho-hum. I can understand the appeal of that idea, but in practice quite a few file formats and applications rely on implicit and/or file-format-specific relationships between multiple files. I.e. I as the user pick one file for opening, but in order to successfully carry out that task, the program actually needs to access quite a few more additional files based on the initially opened file.
None of the sandboxing approaches I've seen so far has a really great story for that usecase.
AFAIK Android and Windows don't offer anything in that regard, no idea about Flatpak, and Apple at least seems to handle related files with differing file extensions, like movie.mp4 and movie.srt, but would still break down for more complex file formats where related/associated files don't share the same file name sans extension.
Plus it means you always have to go through the official OS file dialogues and can't e.g. just manually edit a path directly in the app's UI if that would be more convenient…
I wonder if there was an alternative specifically for the scrollbar here - some way of obtaining an outer "shell" (via win32k, but then basically "orphaning" it so that you can't do anything besides kill it when you're finished) that just provides the window with an empty scrollable element that is then populated by the restricted process.
That ship has really sailed though; I think the days of native widgets are quickly coming to an end.
I guess uxtheme is unsuitable for win32k lockdown for some reason, probably because it's GDI-based.
[1]: https://devblogs.microsoft.com/oldnewthing/20050211-00/?p=36...
You’re right, uxtheme can’t be called directly from content because of win32k dependencies. One option could be for content to request the parent to draw those controls, but as you can imagine there are drawbacks to doing that. As usual, there are a lot of trade offs involved.
I didn’t think Weyland had its own toolkit?
And can you run for example Weyland on Windows?
Also, the problem, I guess, is not just drawing (which could be done securely in a frame-buffer), but that you have to receive the events.
When you write a Windows program, you call APIs from User32.dll, GDI32.dll, and Kernel32.dll. Those are the user mode libraries, and the main entry point to call the Windows API functions.
What's actually inside of those? User32 and GDI32 are pretty much stubs. Mostly, they have a small amount of code, then proceed to call functions in Win32U.dll. Then Win32U.dll makes system calls, causing Win32k (Kernel Mode) to carry out the functions. So everything from BeginPaint to GetWindowText is going to be a system call that's placed from within Win32U, then handled by Win32K.
Meanwhile, Kernel32.dll is a user-mode library (despite the name being "kernel32"), which mostly makes calls to NTDLL.dll. Then NTDLL makes system calls that get handled by kernel-mode components.
The isolation thing that Mozilla is using here does not stop the NTDLL system calls that Kernel32.dll uses, just the calls to Win32U/Win32K (GDI32.dll and User32.dll). So there needs to be other mitigation methods in place for the Kernel32/NTDLL stuff, such as reduced user privileges.
But preventing all the Win32U/Win32K stuff from being called does greatly reduce the attack surface.
I can think of several things you could do to Kernel32 to try to lock it down:
* Patch out all the entry points of Kernel32 you don't want to be used. Then patch out their corresponding entry points out of NTDLL. Then remove the code that invokes the system calls inside of NTDLL. Yes, you can just simply overwrite user mode code willy-nilly as long as you have write access to the process memory.
(Regular programs use the entry points. Someone trying to do something fancy might skip the entry points. If your hackers are using things like ROP chains and gadgets, chances are they don't care about entry points.)
* Create some kind of NT security context so that nothing interesting works anymore. I don't know how this works, but many NT functions want a security context passed in.
* When you are executing code, and you have no idea where Kernel32 is, you can read the module list out of the TEB, and that finds you Kernel32 and NTDLL. Maybe something that could thwart that, but not break code.
In the end though, what could stop the process from attempting to SYSENTER from somewhere besides NTDLL?
That sandbox (and others, for that matter) more or less follow steps as outlined below:
https://blogs.msdn.microsoft.com/david_leblanc/2007/07/27/pr...
https://blogs.msdn.microsoft.com/david_leblanc/2007/07/30/pr...
https://docs.microsoft.com/en-ca/archive/blogs/david_leblanc...
> Even with [Firefox's] attempt at a sandbox […], sites aren't ever cleanly separated into different processes. […] There is no sandbox containing anything afterwards beyond the app sandbox. All sessions and data for other sites is compromised. […] [Compared to Chrome,] Firefox is easier to exploit, [has] lots more low-hanging vulnerabilities and a half-baked weak sandbox. On Android, it has no sandbox at all.
Not saying you are wrong. But maybe you could elaborate and put things into context for me: How does Firefox's sandboxing differ from Chrome's if it's using the Chrome sandbox?
While googling for an answer I found another comment of yours[1] from 5 years ago. Could you possibly speak to what has changed since then and what the current status is? (At least to your knowledge since I understand you no longer work at Mozilla.)
[0]: https://www.reddit.com/r/GrapheneOS/comments/bg03np/browsers...
[1]: https://www.reddit.com/r/firefox/comments/76dxzg/comment/doe...
Keep in mind that, in May of 2017, desktop Firefox did not even yet have full support for multiprocess under particular configurations. Obviously you cannot sandbox content processes that don't exist, so there were some prerequisites that needed to be dealt with first. That was pretty much wrapped up by the Firefox Quantum 57 release.
The other thing to note is that the Chromium Sandbox is more like a "sandbox construction kit." It features all kinds of knobs and dials that allow the developer to configure how strict it is. We used to compare adding multiprocess and sandboxing to Gecko to swapping out the warp drive on the Enterprise, while it was still at warp. You can't just flip a switch one day and be sandboxed; too much code existed under the assumption that it could access whatever OS resources it wanted, without restriction. It took time to modify that code to be aware of that restriction and act accordingly. Each time an iteration of modifications were completed, we were able to tighten the screws on the sandbox a little bit more.
Not only has that been very useful as Gecko has been migrated to running in a fully sandboxed environment, it is also a necessity even at the final stage. For example, modern browsers constrain their interactions with the GPU (and its driver) to a dedicated process. That process is sandboxed, but because that process needs access to graphics devices, it obviously needs a weaker sandbox than the other processes hosting web content.
IMHO the win32k lockdown is not "mission accomplished," but is a HUGE indicator of how much code has been migrated to support sandboxing. On desktop, Firefox processes are now site isolated and are disconnected from their platform GUI systems. That's huge -- I'm sure there are still deviations between the Chrome and Firefox sandbox configurations, but they're a lot closer now.
Firefox for Android still has a long way to go (I was working on that when I left Mozilla), but unfortunately it hasn't been treated with the same urgency as desktop. I know that they're still working on that and have been able to make a lot of progress now that site isolation for desktop has been released.
Finally, I should point out that sandboxing is a defense-in-depth measure, but a lot of armchair quarterbacks seem to only ever want to focus on comparing the sandbox between Chrome and Firefox, while completely ignoring how much more of Firefox is written using memory-safe languages. That's important too.
> Firefox for Android still has a long way to go (I was working on that when I left Mozilla), but unfortunately it hasn't been treated with the same urgency as desktop. I know that they're still working on that and have been able to make a lot of progress now that site isolation for desktop has been released.
This might explain Daniel Micay's perspective on Chrome vs. Firefox (on Android) then.
Chrome is also not immune, very recently had a serious flaw "actively exploited" https://www.bleepingcomputer.com/news/security/google-chrome...
- How expensive is it to discover a new vulnerability in a given app? (This may depend on code base maturity but also on choice of programming language, its inherent memory safety, and supply chain.)
- What privileges does a typical installation of the app grant once RCE is achieved?
- How hard is it to write a working exploit for a newly-discovered vulnerability, taking into account the security architecture that protects the app?
- Given a zero-day exploit, how many times will you have the opportunity to use it? How quickly will other parties discover it, is the vendor willing to provide patches, how long it is going to take, how much do the updates cost, and how difficult is it to upgrade the software in the field?
- Apps and computers tend to come in packs, and attackers love to move laterally. What opportunities would an attacker gain from lateral movement after gaining persistence in a given system?
- Market share and adoption may be skewed, as attackers may be interested in specific targets such as journalists or politicians, who may form a specific demographic with particular adoption rates, which can differ from those of the general population.
if you believe those numbers... 64% vs 3% market share. of course something that impacts 64% of the internet will be more valuable.
that's another sampling of actual web visits. though it skews more tech oriented of course so that's going to be away from safari/ie and more toward firefox and chrome.
/s
It does require one if your system doesn't support user namespaces. Some distros used to disable it, but they're getting rare these days.
But the setuid helper and user namespaces are used for other mitigations that can't be done through bpf. The guys who wrote the bpf sandbox have some nice articles about the distinction which you can probably Google.
I don't know much about the specifics of the implementations, but that seems like a significant difference for such a crucial security feature, especially post meltdown/spectre.
(You mentioned site isolation, which is a different feature, but the dates you have look right for that.)
I think you're confusing the general "sandbox that restricts access to the kernel" with the specific mitigation here. Firefox also had the generic kernel mitigations long ago: https://news.ycombinator.com/item?id=31362935
But it's true Chrome had them first. The same thread points out that Firefox reuses Chrome's sandbox, so like in the first sentence, there are causality constraints that would make it hard for Firefox to support it before Chrome did :-)
In general my recollection is that Chrome splits up more of its components. It sounds like, based on this post, the gpu process is now separated and there's sandboxing efforts going into that, but I'm pretty sure Chrome has had that for years now.
The current mitigations seem to be doubling-down on getting rid of C++ memory safety errors (still the main source of security holes), with Mozilla pulling the Rust and WebAssembly card. So there's some divergence here, rather than parallel paths with one ahead.
I think I agree with the other poster saying that "practically speaking there's probably not a ton of difference".
There used to be a wider gap, but both browsers have all the important stuff now, with any differences being much more incremental. I assume neither is going to get rid of their shitty old C++ codebase anytime soon, which would be the real win.
For sandboxing you're also restricted by what the OS offers in the first place. So expect innovation on Android, or ARM macOS, not Chrome/Firefox on Windows.