How Chromium Uses macOS Seatbelt to Restrict File Access
This article provides a technical overview of how the Chromium web browser leverages Apple's Seatbelt sandbox mechanism on macOS to enforce strict file system access controls. It breaks down the architecture of Chromium's multi-process model, the implementation of Sandbox Profile Language (SBPL) policies, and the specific rules applied to isolate untrusted web content from the underlying operating system's files.
Understanding the macOS Seatbelt Mechanism
Seatbelt is Apple's kernel-level sandboxing technology, built upon the TrustedBSD Mandatory Access Control (MAC) framework. It intercepts system calls made by a process and evaluates them against a strict set of rules. These rules are defined using the Sandbox Profile Language (SBPL), which is based on TinyScheme (a dialect of Lisp). When a process initializes its sandbox, the macOS kernel compiles the SBPL profile into bytecode and enforces those restrictions for the remainder of the process's lifecycle.
Chromium’s Multi-Process Architecture
Chromium operates using a multi-process architecture to separate privileged operations from unprivileged ones. It consists of one main privileged "Browser" process and multiple unprivileged child processes, such as "Renderer" processes (which handle HTML, CSS, and JavaScript), GPU processes, and Utility processes.
The Browser process has full access to the user's file system, within the bounds of the standard macOS user permissions. Conversely, child processes are treated as untrusted and are immediately placed into a Seatbelt sandbox upon creation.
The "Deny by Default" Strategy
When Chromium launches a child process, it uses the macOS
sandbox_init_with_parameters API to apply a specific
.sb (Sandbox) profile before the process begins handling
any web content.
Every Chromium sandbox profile begins with a fundamental rule:
(deny default). This directive instructs the macOS kernel
to block all system operations—including network access, Mach port
lookups, and all file system interactions—unless an explicit
(allow ...) rule is defined later in the profile. By
default, a newly sandboxed Chromium process cannot read, write, or even
check the metadata of a single file on the hard drive.
Granular File System Whitelisting
Because a process cannot function in total isolation, Chromium's
Seatbelt profiles carefully whitelist the absolute minimum file system
paths required for the process to run. Seatbelt divides file access into
specific operations, primarily file-read-data,
file-read-metadata, and file-write*.
Chromium uses dynamic parameters to inject specific paths into the SBPL profile at runtime. A standard child process is only granted read access to:
- System Libraries: Paths like
/System/Libraryand/usr/libso the process can load essential macOS frameworks. - The Chromium Bundle: The specific directory where the Chromium application is installed, allowing the process to read its own executable code and resource files.
- System Configuration Files: Specific files like
/dev/urandomfor cryptography and basic timezone data.
Crucially, file-write* permissions are almost entirely
omitted for most child processes. They cannot create, modify, or delete
files anywhere on the disk.
Locking Down the Renderer Process
The Renderer process is the most heavily restricted component because
it directly parses untrusted code from the internet. In addition to
blocking write access, the Renderer's Seatbelt profile explicitly denies
read access to the user's home directory (~/Documents,
~/Downloads, ~/Desktop, etc.).
Even if an attacker successfully exploits a vulnerability in the V8
JavaScript engine or the Blink rendering engine, the macOS kernel will
block any attempt by the compromised Renderer process to execute
open() or stat() system calls on user
files.
Brokered File Access via IPC
Web browsers occasionally need to access local files, such as when a user uploads a document or saves an image. Because the Renderer process is blocked from the file system by Seatbelt, Chromium uses a "broker" model to handle these legitimate requests.
- The Request: The sandboxed Renderer process sends a message to the privileged Browser process via Mojo, Chromium's Inter-Process Communication (IPC) system.
- Validation: The Browser process evaluates the request to ensure it was initiated by a real user action (such as interacting with a file picker dialog).
- File Descriptor Passing: The Browser process opens the file on behalf of the Renderer. It then passes the open file descriptor (not the file path) back to the Renderer over IPC.
Because Seatbelt primarily restricts the opening of file
paths (via the open system call) rather than reading from
an already-open file descriptor, the Renderer can read the specific
file's data without ever being granted broader access to the macOS file
system.