Meta: Investigate Seccomp profiles on Linux
We should look into how other browsers implement seccomp and other syscall-sandboxing measures for their different process classes.
We should be able to abstract this in a way that's similar to how SerenityOS/OpenBSD's pledge works, to not go crazy with massive syscall list files.
Ideally we would be able to sandbox the WebContent/WebWorker, RequestServer, ImageDecoder, and any future GPU process in a way that they have privileges limited. Locking down at least the ability to create new IPC sockets and requiring those to come from the UI process would be a good first step.
We should also look into similar features for other operating systems.
I spent some time looking into this for Windows and made some very bad and untested code for Windows that I hope to fix eventually. The overall idea is roughly based on the open-source BSD-3 Chromium sandboxing code; I don't know if including Chromium sandboxing code would violate the principals of being an independent browser or if BSD-3 licensed code can be used, although I did make sure to rework a lot of it and it isn't directly adding anything from Chromium as a dependency. More importantly, working on that led me to do more research about sandboxing and mitigation policies.
Basically, the following sandboxing & hardening features are available on Windows:
- Process mitigation policies to restrict access to some potentially dangerous features and configure things like ASLR, DEP, and control flow guard.
- AppContainer as a direct sandboxing API
- Creating separate desktop and window station objects to prevent the Windows "shatter attacks".
- Creating processes with a low-privileged token that has more restrictive access control and integrity policies to reduce process capabilities. (This would require stronger process isolation as some things in Ladybird require more privileges than others.)
-
Running processes inside a restricted
Jobobject to allow restricting a handful of miscellaneous functions.
AppContainer has significantly less compatibility with most of the other mitigations, besides the first one. Therefore, using AppContainer requires not using most of the other mitigations. It's used for Microsoft Edge and UWP apps, but I don't believe that Firefox or Chromium have tried to use it.
As for Linux, I've also been looking into seccomp, user namespaces, bubblewrap, etc. I think the best solution here for Linux is to use seccomp-bpf and also use unprivileged user namespaces whenever they're available. Per https://wiki.mozilla.org/Security/Sandbox/Specifics#Linux:
We're primarily using seccomp-bpf because it's the only thing that's available everywhere (>99% of the Linux Firefox userbase, at last count). There are some weaknesses to using only seccomp-bpf:
- The possibility of overlooking obscure corner cases, like unnamed datagram sockets, that could allow privilege escalation.
- The seccomp-bpf policy can act on argument values, but can't dereference pointer arguments, like the path to open(); in such cases it's necessary to intercept the syscall and message an unsandboxed broker to validate and perform the operation, which adds latency and attack surface. Semantic isolation, like changing the filesystem root or creating a separate network stack with no access to the real network (unsharing the network namespace), has traditionally required superuser privileges. There are two ways to get around this: unprivileged user namespaces and a setuid-root helper executable.
We're using unprivileged user namespaces for additional security where available; they don't require any system-level setup, and 88% of Linux Firefoxes are on a kernel that supports them, according to telemetry. The reason we don't require it (as, for example, gaol does) is the other 12%: some distributions disable the feature because it has its own security risks. (Briefly: it makes subtle changes to authorization semantics, and it exposes kernel attack surface that's normally restricted to root; both of these have led to local privilege escalation vulnerabilities in the past.)
But I obviously don't claim to be very knowledgeable on this, I just hope some of my thoughts might be useful if anyone is going to be looking into sandboxing