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/Library and /usr/lib so 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/urandom for 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.

  1. The Request: The sandboxed Renderer process sends a message to the privileged Browser process via Mojo, Chromium's Inter-Process Communication (IPC) system.
  2. 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).
  3. 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.