[tbb-dev] Sandboxing Tor Browser - A New Beginning (?)
Matthew Finkel
matthew.finkel at gmail.com
Tue Jul 3 18:03:07 UTC 2018
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/Microsoft.Windows.ComputeVirtualization/Hcs.cs#L130
[5] https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-setprocessmitigationpolicy
[6] https://docs.microsoft.com/en-us/previous-versions/windows/apps/hh464936(v=win.10)
[7] https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AboutAppSandbox/AboutAppSandbox.html
[8] https://help.apple.com/xcode/mac/current/#/dev88ff319e7
[9] https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW1
[10] https://trac.webkit.org/browser/webkit/releases/Apple/Safari%2011.1.1/WebKit/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in
[11] https://www.chromium.org/developers/design-documents/sandbox/osx-sandboxing-design
[12] https://wiki.mozilla.org/Security/Sandbox#OSX
[13] https://dxr.mozilla.org/mozilla-central/source/security/sandbox/mac/SandboxPolicies.h
[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-platform-start-page
[18] https://docs.microsoft.com/en-us/windows/desktop/FWP/permitting-and-blocking-applications-and-users
[19] https://docs.microsoft.com/en-us/virtualization/windowscontainers/container-networking/architecture
[20] https://github.com/Microsoft/hcsshim/blob/master/internal/hns/namespace.go#L61
[21] https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW9
[22] https://gitweb.torproject.org/builders/tor-browser-build.git/tree/projects/tor-browser/Bundle-Data/mac-sandbox?h=tbb-7.5.6-build4
[23] https://github.com/Microsoft/hcsshim/blob/master/internal/wclayer/createlayer.go#L10
[24] https://github.com/Microsoft/hcsshim/blob/master/internal/wclayer/createscratchlayer.go
[25] https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW24
[26] https://trac.torproject.org/projects/tor/wiki/doc/TorBrowser/Sandbox/Linux#HowdoIgetsoundtowork
More information about the tbb-dev
mailing list