Hi All,
This is the beginning of a conversation about creating a plan for moving towards sandboxing Tor Browser on every platform. Over the last few years, there existed a Sandboxed Tor Browser on only Linux[0] (created and maintained by Yawning Angel). However, Tor Browser aims at providing a Private Browser on all supported platforms (Microsoft Windows, Apple Mac OS X, GNU/Linux, and Android (AOSP))[1][2], this means we must provide a sandboxed run-time environment on all platforms. Unfortunately, each operating system provides a unique set of sandboxing techniques and capabilities, so we must work with the facilities we are given. In some cases, we may need to be creative about how we achieve our goals.
I do not have all the answers, and there are some open questions below.
On Windows, we have the Windows integrity mechanism[3], Windows Containers[4], SetProcessMitigationPolicy[5], App Container[6], and maybe some others. Some of this functionality is already used by Firefox.
On Mac OS X, there are two sandboxing techniques available. The first is Seatbelt[7]. Apple deprecated it in favor of code signing entitlements[8]. Unfortunately, the code signing entitlements are not as fine-grained as those Seatbelt provides, but we can enable different entitlements per "target"[9]. I don't know if this will be difficult for us. Therefore, we should utilize the code-signing restrictions where they are appropriate, but we should follow Safari[10], Chromium[11], and Firefox[12][13] by applying restrictive Sealtbelt policies where applicable.
On GNU/Linux, we can use the namespacing and secure computing (Secure Computing) facilities in the kernel exposed to userspace. Sandboxed Tor Browser on Linux already shows how these can be combined and form a sandbox. In particular, we can use bubblewrap[14] as a setuid sandboxing helper (if user namespace is not enabled), if it is available. In addition, we can reduce the syscall surface area with Seccomp-BFP. CGroups provide a way for limiting the resources available within the sandbox. We may also want to manually proxy/filter other system functionality (X11).
Last, but not least, on Android, we begin with a fairly strict sandbox provided by its permissioning model[15], distinct per-app users, and SELinux policies. Because every app is run using a distinct user, and each has its own storage directories, we get Linux's DAC on the file system for "free". In addition, we can use some of the same techniques available on GNU/Linux on Android, namely the seccomp-bpf and namespaces, if they are available. Android provides privilege and permission isolation within an App by using Services. With some refactoring, we can isolate some parts of Firefox into isolated permissionless services[15].
I'll begin by describing the goals, as I see it, for sandboxing Tor Browser. Hopefully, this will help us evaluate the different available techniques. These goals are derived from the Design document[16] and are the means for archieving Tor Browser's end-goal.
In particular, the sandboxing techniques preserve the Security Requirements of a private browser when the browser, itself, fails at maintaining those criteria. By this I mean the sandbox should be designed such that if the browser process loses any of the Security properties (through a logical bug, exploited vulnerability, etc), the sandbox provides an additional layer of those properties and the user is not in immediate danger. The sandbox may, in some situations, improve the Privacy properties of Tor Browser, for example if a component/device is emulated instead of providing the browser with raw access. We should use these mechanisms when they are available.
1) Proxy Obedience 2) State Separation 3) Disk Avoidance 4) Application Data Isolation 5) Secure Updating 6) Usable 7) Cross-Origin Fingerprinting Unlinkability
We'll go through these one-by-one and describe the role of a sandbox and how we can achieve this on each platform. Note, this design assumes a launcher-based sandboxed architecture (similar to the Sandboxed Tor Browser on Linux):
------------------ | Launcher | ------------------ | | ------------------------------ | | | | v | | ---------------- | v | Sandbox | v ----------------- | ----------- | ----------------- | Sandbox | | | Broker | | | Sandbox | | ------------- | | ----------- | | ------------- | | | Firefox | | --------------- | | Tor | | | ------------- |------/ _________| ------------- | ----------------- Controller ----------------- |____________________________________| Proxy IPC
Note, the sandboxed broker process (or processes) moves some functionality from the launcher process into a child process. This process is not as heavily sandboxed as the Firefox and Tor process, but, for example it would not need networking. This process would handle sending NEWNYM, provide a circuit display, change bridge configuration (general controller functions). In addition, it would handle copying files into and out of the Firefox sandbox, as an example.
Unfortunately, there is not an existing cross-platform solution for this design. We can take bits-and-pieces from other solutions, creating this will require engineering effort.
1) Proxy Obedience
The last line of defense against a proxy-bypass is a mechanism for dropping all outgoing IP packets from the browser that are: - not TCP - or TCP but not destined for the Tor proxy port (SOCKS or HTTP) - or all packets (including TCP) if the proxy listener is not a TCP port (Unix domain socket, named pipe, etc)
We should also consider guarding the creation of all non-Unix domain sockets and non-named pipes with a pref. I believe sandboxing should be optional, but enabled by default (at least with first few versions), so excluding that code at compile-time is not an option. However, a pref-guard only stops unintended proxy-bypass through normal control flow. This only slightly increases the difficulty of some exploit methods.
Per-platform sandboxing techniques: a) Microsoft Windows i) Windows 8+ If the user can elevate for administrator permissions, then the launcher can: - install a network filter using the Windows Filter Platform[17]. This can deny any connection from any process (based on the process's fully-qualified file name)[18]. This adds some risk because if the launcher process exits unexpected for whatever reason, the firewall rule may remain in place. ii) Windows 10 We can create a new network namespace[19] using the (undocumented) HNSCall procedure[20]. This is very appealing. iii) Windows 7+ If the platform is Windows 8+ and the user cannot elevate to Administrator or if the platform is Windows 7: - TODO: can/should we use DLL injection of WinSocks and manually filter all proxy-bypass network connections? Is there something we can use for mitigating ROP gadgets within the sandbox?
b) Mac OS X i) We can restrict network access using the com.apple.security.network.client and com.apple.security.network.server entitlements[21]. ii) We can further restrict which types of connections the browser is allowed. Previously, there was a seatbelt profile for Tor Browser[22], but it is not usable with newer versions of the browser. We can continue using it for only allowing access requests for Unix domain sockets, and denying all other network connections.
c) GNU/Linux i) On Linux, significant progress was already made in terms of sandboxing Tor Browser. There are two methods we can use: - Isolated network namespace via bubblewrap[14] - Seccomp-BPF on socket syscalls ii) If bubblewrap is not available, we can fallback on using unshare if it is available and user namespace is enabled iii) If user namespaces are not avialable, we ask the user for elevated privileges and manually fork into the new network namespace (worst-case).
d) Android i) We can use the same (or similar) Seccomp-BPF filter that we use on Linux ii) We can move the Gecko service into an isolated process without any permissions (including Networking). iii) If all networking goes through Necko, and Neck is in the isolated process, then the remaining code, outside the isolated process, should be proxy-safe or it is the tor process.
2) State Separation
Per-platform sandboxing techniques: a) Microsoft Windows i) I'm not sure if there is more we can do here.
b) Mac OS X i) The Seatbelt profile[22] can restrict access to all other Firefox profiles ii) The Seatbelt profile can only allow access for bundled libraries iii) We may exclude entitlements for most system services
c) GNU/Linux i) We can create new IPC, mount, and uts namespaces ii) We can provide a clean environment iii) The new mount namespace contains only the required bundled libraries required for running iv) D-Bus/I-Bus access would be nice, if we can do it safely.
d) Android i) All apps are isolated by default, so there should never be shared state. ii) Ensure we have the smallest set of intent filters we need iii) Ensure we have the smallest set of exported components we need iv) Ensure we have the smallest set of broadcast receivers we need v) Ensure we only use Broadcast intents where it is necessary vi) Is there something else we should investigate here?
3) Disk Avoidance In general, I'd like #7449 mitigated.
Per-platform sandboxing techniques: a) Microsoft Windows i) Windows 10+ - On very recent versions of Windows, we can create temporary filesystem Layers[23][24]. I'm not sure if these are memory-backed or filesystem-backed. - We can create a read-only layer over the installation directory - #18367 may be useful (side-by-side user/app data on Windows) - Can we can isolate the container from system services?
b) Mac OS X i) We can use entitlements[25] ii) The Seatbelt profile[22] provided additional access restrictions. iii) Is there a filesystem layering mechanism available in OS X (like tmpfs in Linux)? - Specifically, if we can use this for ~/Library/Caches/TemporaryItems and ~/Downloads
c) GNU/Linux i) We can create new IPC, mount, and uts namespaces ii) #18369 may be useful (side-by-side user/app data on Linux)
d) Android i) The app is self-contained by default ii) Need #26574 iii) Additional auditing required
4) Application Data Isolation I'll claim the per-platform sandboxing techniques are the same as Disk Avoidance.
5) Secure Updating Nearly the same sandboxing techniques can be used on all platforms. A launcher-component (maybe not the launcher, but a reduced-privileged process, not the browser) downloads the update. Next, on download completion, a launcher-component verifies the download and installs it (I can't justify verifying the download in an unprivileged, sandboxed process - I'd like to do it, but I don't see a benefit).
a) Microsoft Windows i) Layer read-only filesystem on top of install dir, prevents presistant modifications
b) Mac OS X i) Seatbelt profile prevents write access of app binaries
c) GNU/Linux i) Mount namespace provides read-only access of install dir ii) Mount namespace does not include launcher binaries
d) Android i) If App was installed using a App Store, then that is responsible for updating ii) If the app was installed by the user (side-loaded), then the we can isolate downloading into a separate process, and then verification can be handled in an isolated process. Finally, the Android Package Manager controls installing the update.
6) Usable
Unfortunately, despite the above suggestions, this sandboxing model fails if users find its unusable. In particular, with temporary file systems, we should provide a method for safely extracting a file from the temporary location and copying it to a permanent location using the launcher process. In addition, exposing operating system functionality which may be fingerprintable and/or another attack vector should be optional if it unbreaks the web (such as providing pulseaudio on Linux[26]). As usual. we must be careful about giving users too many customizable switches.
7) Cross-Origin Fingerprinting Unlinkability
I've less experience here on non-Linux OS (and Sandboxed Tor Browser is already a good base on Linux). Which other components should we consider spoofing (if possible) or go out of our way and disallow access (if not possible using the above means)?
[0] https://trac.torproject.org/projects/tor/wiki/doc/TorBrowser/Sandbox/Linux [1] https://www.mozilla.org/en-US/firefox/60.0esr/system-requirements/ [2] https://support.mozilla.org/en-US/kb/will-firefox-work-my-mobile-device [3] https://msdn.microsoft.com/en-us/library/bb625963.aspx [4] https://github.com/Microsoft/dotnet-computevirtualization/blob/master/src/Mi... [5] https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-pr... [6] https://docs.microsoft.com/en-us/previous-versions/windows/apps/hh464936(v=w...) [7] https://developer.apple.com/library/archive/documentation/Security/Conceptua... [8] https://help.apple.com/xcode/mac/current/#/dev88ff319e7 [9] https://developer.apple.com/library/archive/documentation/Security/Conceptua... [10] https://trac.webkit.org/browser/webkit/releases/Apple/Safari%2011.1.1/WebKit... [11] https://www.chromium.org/developers/design-documents/sandbox/osx-sandboxing-... [12] https://wiki.mozilla.org/Security/Sandbox#OSX [13] https://dxr.mozilla.org/mozilla-central/source/security/sandbox/mac/SandboxP... [14] https://github.com/projectatomic/bubblewrap [15] https://developer.android.com/reference/android/Manifest.permission [15] https://developer.android.com/guide/topics/manifest/service-element#isolated [16] https://www.torproject.org/projects/torbrowser/design/ [17] https://docs.microsoft.com/en-us/windows/desktop/FWP/windows-filtering-platf... [18] https://docs.microsoft.com/en-us/windows/desktop/FWP/permitting-and-blocking... [19] https://docs.microsoft.com/en-us/virtualization/windowscontainers/container-... [20] https://github.com/Microsoft/hcsshim/blob/master/internal/hns/namespace.go#L... [21] https://developer.apple.com/library/archive/documentation/Miscellaneous/Refe... [22] https://gitweb.torproject.org/builders/tor-browser-build.git/tree/projects/t... [23] https://github.com/Microsoft/hcsshim/blob/master/internal/wclayer/createlaye... [24] https://github.com/Microsoft/hcsshim/blob/master/internal/wclayer/createscra... [25] https://developer.apple.com/library/archive/documentation/Security/Conceptua... [26] https://trac.torproject.org/projects/tor/wiki/doc/TorBrowser/Sandbox/Linux#H...