Skip to content

Root Code Execution via Git Hooks in macOS `.pkg` Postinstall

Moderate
MikeMcQuaid published GHSA-6689-q779-c33m Apr 27, 2026

Package

postinstall (shell)

Affected versions

5.1.6

Patched versions

5.1.8

Description

Affected components:

  • package/scripts/postinstall:29-35
  • package/scripts/postinstall:37-60

Why this is a vulnerability

The postinstall script runs Git commands inside the installed Homebrew repository before any hardening step disables hooks:

cd "${homebrew_directory}"
git config --global --add safe.directory "${homebrew_directory}"
git checkout --force -B stable
git reset --hard "$(git tag --list --sort="-version:refname" | head -n1)"
git clean -f -d

Code reference:

  • package/scripts/postinstall:29-35

On Intel systems with an existing /usr/local/Homebrew, the script first copies the packaged .git directory into the existing installation:

cp -pRL "${homebrew_directory}/.git" "/usr/local/Homebrew/"
...
git -C /usr/local/Homebrew checkout --force -B stable

Code reference:

  • package/scripts/postinstall:42-49

This matters because:

  • git checkout executes the repository's post-checkout hook.
  • the installer path is privileged;
  • Homebrew intentionally leaves the installation writable by a non-root user after install, so an existing installation is attacker-modifiable in common deployments;
  • the script never disables hooks with core.hooksPath=/dev/null, -c core.hooksPath=/dev/null, or a sanitized GIT_DIR.

Root cause

The privileged installer script treats the on-disk Git repository as inert package data, but then executes a hook-triggering Git command inside it.

That assumption is false for two distinct deployment modes:

  1. Apple Silicon / /opt/homebrew update path: the installer runs Git directly in the target installation directory.
  2. Intel / /usr/local/Homebrew update path: the installer merges packaged .git content into an existing .git tree, which preserves any attacker-added extra hook files not present in the package payload.

Preconditions

  • The victim machine already has a Homebrew installation writable by a local user.
  • An administrator, installer GUI session, or MDM later installs or upgrades using the official Homebrew .pkg.

This is realistic in enterprise/macOS lab settings because the package exists specifically to support managed deployment, while Homebrew intentionally avoids requiring sudo for normal operation.

Deterministic POC

Runnable POC in this directory:

  • poc_pkg_git_hook_lpe.sh

What it does:

  1. Creates a fake existing Homebrew Git repository.
  2. Installs a malicious .git/hooks/post-checkout.
  3. Replays the same Git command sequence used by package/scripts/postinstall.
  4. Shows that the hook runs in the installer's execution context.
  5. Demonstrates the Intel-specific merge behavior that preserves attacker-supplied hook files.

Observed result during validation:

  • The hook executed successfully when the mirrored git checkout --force -B stable command ran.
  • A separate reproduction confirmed that cp -pRL "$src/.git" "$dst/" preserved an existing post-checkout hook in the destination .git/hooks/.

Direct validation on installed Homebrew 5.1.6

I validated this primitive against the actual installed Homebrew on this host:

  • brew --version reported Homebrew 5.1.6
  • brew --repository reported /opt/homebrew
  • the repository was on branch stable at commit 299ab19496df6fc76e8356c0b87100ff91ef827e

Using a temporary hook in /opt/homebrew/.git/hooks/post-checkout and a disposable linked worktree, checkout in the worktree caused the hook from the real installed repository to execute. The observed log entries were:

hook_ran uid=502 cwd=/private/tmp/homebrew-worktree.2iTwey old=0000000000000000000000000000000000000000 new=299ab19496df6fc76e8356c0b87100ff91ef827e flag=1
hook_ran uid=502 cwd=/private/tmp/homebrew-worktree.2iTwey old=299ab19496df6fc76e8356c0b87100ff91ef827e new=299ab19496df6fc76e8356c0b87100ff91ef827e flag=1

This was a non-destructive user-context confirmation only, but it proves the crucial behavior on the real Homebrew 5.1.6 installation: Git operations against the installed repository do execute post-checkout from the repository's hooks directory. When the package installer runs the same Git sequence as root, the privilege boundary is what changes, not the trigger mechanism.

Step-by-step manual reproduction

  1. On a system with an existing writable Homebrew installation, create an executable hook:

    cat > /opt/homebrew/.git/hooks/post-checkout <<'EOF'
    #!/bin/sh
    /usr/bin/id -u > /tmp/homebrew-pkg-hook.uid
    EOF
    chmod +x /opt/homebrew/.git/hooks/post-checkout
  2. Have an administrator install or upgrade using the official Homebrew .pkg.

  3. After installation, inspect /tmp/homebrew-pkg-hook.uid.

  4. If the install ran with root privileges, the file contains 0.

Intel variant:

  1. Place the hook in /usr/local/Homebrew/.git/hooks/post-checkout.
  2. Run the .pkg installer on an Intel machine with an existing /usr/local/Homebrew.
  3. The cp -pRL .../.git /usr/local/Homebrew/ step preserves the extra hook and the subsequent git -C /usr/local/Homebrew checkout --force -B stable executes it as root.

Impact

  • Direct local privilege escalation to root.
  • Straightforward persistence in managed environments that use the official .pkg for installation or upgrades.
  • MDM-triggered deployment turns this into a highly reliable privilege boundary break: the attacker only needs write access to the existing Homebrew installation and patience.

Likelihood and exploitability

  • Exploitability: High
  • Reliability: High
  • User interaction: Low after initial foothold

The only meaningful requirement is that a privileged package install happens after the attacker places the hook.

Recommended remediation

Priority: Immediate

  1. In package/scripts/postinstall, disable hooks for every Git invocation, for example:

    git -c core.hooksPath=/dev/null checkout --force -B stable
    git -c core.hooksPath=/dev/null reset --hard ...
    git -c core.hooksPath=/dev/null clean -f -d
  2. Replace the Git-based normalization step with a non-hookable approach if possible.

  3. Before operating on an existing installation, remove .git/hooks or replace the entire .git directory atomically rather than merging into it.

  4. Treat package-time repository content as untrusted if the target installation may already exist and be user-writable.

Public reporting check

I found no matching public report for this exact issue in:

  • Homebrew installation docs
  • Homebrew's published penetration test report
  • Homebrew's published comprehensive 2024 security assessment
  • targeted searches for Homebrew Git-hook/package-installer reports on GitHub and the public web

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v4 base metrics

Exploitability Metrics
Attack Vector Local
Attack Complexity Low
Attack Requirements Present
Privileges Required Low
User interaction Active
Vulnerable System Impact Metrics
Confidentiality High
Integrity High
Availability High
Subsequent System Impact Metrics
Confidentiality None
Integrity None
Availability None

CVSS v4 base metrics

Exploitability Metrics
Attack Vector: This metric reflects the context by which vulnerability exploitation is possible. This metric value (and consequently the resulting severity) will be larger the more remote (logically, and physically) an attacker can be in order to exploit the vulnerable system. The assumption is that the number of potential attackers for a vulnerability that could be exploited from across a network is larger than the number of potential attackers that could exploit a vulnerability requiring physical access to a device, and therefore warrants a greater severity.
Attack Complexity: This metric captures measurable actions that must be taken by the attacker to actively evade or circumvent existing built-in security-enhancing conditions in order to obtain a working exploit. These are conditions whose primary purpose is to increase security and/or increase exploit engineering complexity. A vulnerability exploitable without a target-specific variable has a lower complexity than a vulnerability that would require non-trivial customization. This metric is meant to capture security mechanisms utilized by the vulnerable system.
Attack Requirements: This metric captures the prerequisite deployment and execution conditions or variables of the vulnerable system that enable the attack. These differ from security-enhancing techniques/technologies (ref Attack Complexity) as the primary purpose of these conditions is not to explicitly mitigate attacks, but rather, emerge naturally as a consequence of the deployment and execution of the vulnerable system.
Privileges Required: This metric describes the level of privileges an attacker must possess prior to successfully exploiting the vulnerability. The method by which the attacker obtains privileged credentials prior to the attack (e.g., free trial accounts), is outside the scope of this metric. Generally, self-service provisioned accounts do not constitute a privilege requirement if the attacker can grant themselves privileges as part of the attack.
User interaction: This metric captures the requirement for a human user, other than the attacker, to participate in the successful compromise of the vulnerable system. This metric determines whether the vulnerability can be exploited solely at the will of the attacker, or whether a separate user (or user-initiated process) must participate in some manner.
Vulnerable System Impact Metrics
Confidentiality: This metric measures the impact to the confidentiality of the information managed by the VULNERABLE SYSTEM due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.
Integrity: This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. Integrity of the VULNERABLE SYSTEM is impacted when an attacker makes unauthorized modification of system data. Integrity is also impacted when a system user can repudiate critical actions taken in the context of the system (e.g. due to insufficient logging).
Availability: This metric measures the impact to the availability of the VULNERABLE SYSTEM resulting from a successfully exploited vulnerability. While the Confidentiality and Integrity impact metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) used by the system, this metric refers to the loss of availability of the impacted system itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of a system.
Subsequent System Impact Metrics
Confidentiality: This metric measures the impact to the confidentiality of the information managed by the SUBSEQUENT SYSTEM due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.
Integrity: This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. Integrity of the SUBSEQUENT SYSTEM is impacted when an attacker makes unauthorized modification of system data. Integrity is also impacted when a system user can repudiate critical actions taken in the context of the system (e.g. due to insufficient logging).
Availability: This metric measures the impact to the availability of the SUBSEQUENT SYSTEM resulting from a successfully exploited vulnerability. While the Confidentiality and Integrity impact metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) used by the system, this metric refers to the loss of availability of the impacted system itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of a system.
CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N

CVE ID

No known CVE

Weaknesses

No CWEs

Credits