Medium chrome OOB 📄 Reporter bug report

Overview

Medium
Severity
—
CVSS
No
Exploited ITW
Embargoed
Fix Status
ImpactOut of bounds read in Installer
DescriptionOut of bounds read in Installer
ComponentInstaller
Sub-componentInternals>Installer
Bug ClassOOB
Tracker520429499
CISA KEVNot listed
CreditedGoogle
Disclosed2026-10-20

Fix not yet public

No public source fix for this bug has been identified on the main branch yet — it is embargoed or not yet disclosed. Root-cause analysis is withheld until the fix commit is available.

Original Bug Report

reported by vm...@google.com

MacOS Installer TOCTOU Local Privilege Escalation in postinstall Script

Project Fortify, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.

Overview: A potential TOCTOU vulnerability exists in the macOS installer where postinstall executes an updater binary from /Applications as root. Because /Applications is group-writable by admin on macOS, an admin-group attacker can race the installer to swap the path. This allows a local administrative user to potentially escalate privileges to root.

Affected files:

  • chrome/installer/mac/pkg_postinstall.in
  • chrome/installer/mac/pkg_preinstall.in
  • chrome/installer/mac/signing/pipeline.py
  • chrome/installer/mac/signing/config.py

Estimated timestamp from git blame: 2023-11-03

Potential macOS Installer TOCTOU Local Privilege Escalation in postinstall Script

Overview

During a system-wide macOS .pkg installation of Chrome, the post-installation script runs with root privileges and directly executes the GoogleUpdater binary from under /Applications without verifying its code signature or copying it to a safe location. Because /Applications is writable by the admin group on default macOS installations (and lacks a sticky bit), a local attacker in the admin group can potentially race the installer to swap the directory tree with a malicious payload, resulting in execution of arbitrary code as root.

Root Cause Analysis

In chrome/installer/mac/pkg_postinstall.in:

readonly INSTALLATION_PATH=${2}
...
readonly FRAMEWORK_DIR="@FRAMEWORK_DIR@"
...
# 1. Install GoogleUpdater.
echo "Installing GoogleUpdater."
"${INSTALLATION_PATH}/${FRAMEWORK_DIR}/Helpers/GoogleUpdater.app/Contents/MacOS/GoogleUpdater" "--install" "--system"
  1. The installer script runs as root (due to <domains enable_localSystem="true" ... /> in the distribution XML, configured in chrome/installer/mac/signing/pipeline.py).
  2. $2 points to the target installation directory, which defaults to /Applications (--install-location /Applications in pipeline.py).
  3. @FRAMEWORK_DIR@ expands to Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework.
  4. Therefore, the command executes a binary from: /Applications/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Helpers/GoogleUpdater.app/Contents/MacOS/GoogleUpdater

On macOS, /Applications is owned by root:admin with permissions drwxrwxr-x. Any local process running in the admin group can rename a root-owned directory inside /Applications using the standard rename(2) system call because the write permission on the parent directory governs the ability to rename entries within it.

The pre-installation script pkg_preinstall.in only verifies that the application location does not contain a symlink or an incorrect bundle ID, but it runs before payload extraction and does not offer protection for the window of time between extraction and the execution of postinstall.

Potential Trigger Path (Theoretical)

Note: These steps are suggested/potential steps; our tooling does not yet have the ability to run code or verify live exploits.

  1. An attacker with local admin-group access prepares a malicious directory tree at /Applications/.staged-evil.app containing a payload at Contents/Frameworks/Google Chrome Framework.framework/Helpers/GoogleUpdater.app/Contents/MacOS/GoogleUpdater.
  2. The attacker monitors /Applications using FSEvents or kqueue for the creation of Google Chrome.app.
  3. When the installer package starts extracting the payload, the attacker’s script races the installer to perform: rename("/Applications/Google Chrome.app", "/Applications/Google Chrome.app.orig") rename("/Applications/.staged-evil.app", "/Applications/Google Chrome.app")
  4. The installer completes extraction and proceeds to run postinstall as root.
  5. The postinstall script executes the binary at the expected sub-path, spawning the attacker’s payload with euid=0 (root).

Fix Suggestion

An analogous root execution flow was already hardened in the privileged helper tool chrome/updater/mac/privileged_helper/service.mm (via VerifyUpdaterSignature).

To address this vulnerability, the installer scripts or updater initiation should adopt a similar pattern:

  1. Copy the updater bundle from the target installation path /Applications to a root-only temporary directory (e.g., using mktemp -d or a unique path created under /private/var/tmp owned strictly by root:wheel with 0700 permissions).
  2. Verify the code signature of the copied bundle (e.g., checking the cryptographic signature and matching the expected Team ID) using system utilities (such as codesign --verify or SecStaticCodeCheckValidity).
  3. Execute GoogleUpdater from that secure, verified temporary directory.

Evaluated with Chrome root at commit: e9507a33bb4148ee071aaaf8a7e9ad68770359bf


Results so far have been promising, but there can be wrong deductions. Feel free to adjust as follows:

  • If you are familiar with the severity guidelines, you may adjust the severity.
  • If this is a false positive, and there’s no work to be done, please close as WAI.
  • If there is work to do here but not a vulnerability, please change the issue type to Task/Bug/FR.

Data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.

View on issue tracker