Skip to content

Require trust for automatic tap migration installs - #23662

Merged
MikeMcQuaid merged 1 commit into
Homebrew:mainfrom
felix314159:main
Aug 26, 2026
Merged

Require trust for automatic tap migration installs#23662
MikeMcQuaid merged 1 commit into
Homebrew:mainfrom
felix314159:main

Conversation

@felix314159

@felix314159 felix314159 commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

What

Require the exact formula or cask migration target to be trusted before brew update installs it automatically. Untrusted targets are now skipped with explicit brew trust and brew install instructions.

Why

An installed but untrusted third-party tap can provide tap_migrations.json. For deleted casks, Reporter#migrate_tap_migration checks only whether Caskroom/ exists. It does not verify that the installed cask originated from the tap being updated.

A compromised dormant tap can therefore:

  1. Add an untrusted cask entry colliding with an unrelated installed cask.
  2. Later delete that entry and migrate it to an attacker-controlled formula.
  3. Cause brew update to invoke a fully qualified installation of that formula.

brew install passes fully qualified names to Trust.trust_fully_qualified_items!, so the new formula becomes trusted before its Ruby is evaluated.

A plausible scenario that could happen is:

brew install abc/tools/abc
brew uninstall abc

So the user installed something (that is not yet compromised), and uninstalled it after a while (abc is still not compromised). The main problem here is that uninstalling abc only removes its item-specific trust but leaves abc/tools tapped. If that dormant tap is compromised months later, it can target an unrelated installed cask such as:

brew install --cask google-chrome

The victim then only needs to run this any point in time:

brew update

and now is compromised.

Reproduction

I prepared a dependency-free Python PoC as gist.

Fix

Both automatic migration-install branches now require Homebrew::Trust.trusted? for the exact destination type and fully qualified name. Official taps and explicitly trusted targets continue to migrate automatically. Untrusted targets receive commands for completing the migration deliberately. A test case covers refusal of an untrusted migration target.

Verification

brew typecheck
No errors! Great job.

brew style --changed --fix
2 files inspected, no offenses detected

brew tests --changed --online
38 examples, 0 failures

brew lgtm --online passes.

  • Have you followed our Contributing guidelines?
  • Have you checked for other open Pull Requests for the same change?
  • Have you explained what your changes do? Performance claims (e.g. "this is faster") must include brew benchmark results.
  • Have you explained why you'd like these changes included, not just what they do?
  • For bug fixes, have you given step-by-step brew commands to reproduce the bug?
  • Have you written new tests (excluding integration tests)? Here's an example.
  • Have you successfully run brew lgtm (style, typechecking and tests) locally?

  • I did not use AI/LLM to create this PR, or I disclosed the tool/model below and reviewed its output; I did not attribute commits to AI and will answer maintainer questions and review comments myself without AI/LLM.

I used no AI to assist with investigating the issue, developing and testing the fix, and drafting this description. I reviewed the resulting changes, reproduced the vulnerability and fix, and ran brew lgtm --online successfully. I will answer maintainer questions and review comments myself without AI/LLM.


@github-actions

Copy link
Copy Markdown
Contributor

Thanks for your pull request. This has been closed because it appears to be missing the pull request template, perhaps because this was written by an AI not a human. We require humans to read and fill in these templates.

Please edit this pull request to fill in the current pull request template. This workflow will reopen this pull request automatically once the template is complete. Do not open a new pull request for this.

@github-actions github-actions Bot closed this Aug 26, 2026
@github-actions github-actions Bot reopened this Aug 26, 2026

@MikeMcQuaid MikeMcQuaid left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea and implementation. Makes a lot of sense. Thanks!

@MikeMcQuaid
MikeMcQuaid added this pull request to the merge queue Aug 26, 2026
Merged via the queue into Homebrew:main with commit e6a9053 Aug 26, 2026
94 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants