So überprüfst Du Homebrew-Pakete vor einem Upgrade auf CVEs

Es ist Montagmorgen, Du hast Deinen Kaffee in der Hand und führst brew upgrade aus, um Deine Tools auf den neuesten Stand zu bringen – gh, ImageMagick, einen Datenbank-Client, was auch immer über das Wochenende veraltet ist. Eine Liste scrollt vorbei, Du drückst die Eingabetaste, und Homebrew lädt fröhlich die neueste Version von jedem Programm herunter und installiert sie. Es ist wahrscheinlich der Befehl, auf den Du Dich im Alltag am meisten verlässt: Homebrew ist die Quelle für die Entwickler-Tools Deines Macs, also hältst Du es natürlich auf dem neuesten Stand. Aktualisieren ist doch das Verantwortungsbewusste, oder?

Hier ist die Annahme, die hinter dieser Gewohnheit steckt. brew upgrade fragt nie nach, ob die neue Version, die es gerade installieren will, eine bekannte Sicherheitslücke enthält – oder ob das Rezept, das sie beschreibt, still und leise geändert wurde. Es fetcht einfach die neueste Version und führt sie aus. Die Pakete von Homebrew werden nicht auf Sicherheit geprüft: Es handelt sich um Formeln, die von Freiwilligen in öffentlichen Taps gepflegt werden, und eine einzige kompromittierte Formel oder ein gekaperter Tap erreicht jeden Rechner, der von dort aus ein Upgrade durchführt. An den meisten Morgen ist das völlig in Ordnung. An dem einen Morgen, an dem das nicht der Fall ist, hast Du einer brandneuen, bösartigen Binärdatei die Kontrolle über Deinen Laptop überlassen – und das hast Du absichtlich getan, mit dem Befehl, dem Du am meisten vertraust.

Außerdem ist es selten nur das eine Tool, das Du eigentlich aktualisieren wolltest. Das Aktualisieren einer einzigen Formel kann eine Handvoll dependencies nachziehen oder aktualisieren, von denen jede einzeln von ihrem jeweiligen maintainer heruntergeladen wird, und brew upgrade überprüft keine davon anhand einer Datenbank mit Schwachstellen – dafür ist es einfach nicht gedacht. homebrew-safe-upgrade macht genau das, wofür es gedacht ist: Bevor irgendetwas installiert oder aktualisiert wird, überprüft es die Zielversion jedes Pakets sowie die damit einhergehenden dependencies und lässt nur die einwandfreien durch.

Das Problem, ganz einfach ausgedrückt

Es gibt eigentlich drei verschiedene Arten, wie ein brew upgrade Dir schaden kann, und das Standard-Homebrew schützt vor keiner davon. Die offensichtlichste ist eine bekannte Schwachstelle: Für die neue Version gibt es einen veröffentlichten CVE, und Du installierst sie trotzdem, weil Du nicht nachgeschaut hast. Die zweite ist die Aktualität: Die gefährlichste release ist oft die, die vor einer Stunde veröffentlicht wurde – in der Lücke zwischen dem Diebstahl der Zugangsdaten eines maintainers durch einen Angreifer und dem Zeitpunkt, an dem die Welt davon Notiz nimmt – viel zu neu, als dass sie schon in einer CVE-Datenbank aufgeführt wäre. Der dritte Punkt ist Manipulation: Ein gekaperter Tap kann eine andere Binärdatei unter einer Versionsnummer ausliefern, der Du bereits vertraust, sodass die Versionszeichenfolge normal aussieht, während die Bytes es nicht sind.

Wem passiert das schon?

Jeder Entwickler unter macOS oder Linux, der Homebrew nutzt – also die meisten von ihnen – und jede CI-Pipeline, die ihre Toolchain mit brew install ausführt. Keiner von ihnen liest das Changelog jeder transitiven Abhängigkeit, bevor er die Eingabetaste drückt; der Sinn von brew upgrade besteht ja gerade darin, dass man sich darüber keine Gedanken machen muss. Genau deshalb gehört die Überprüfung in den Befehl selbst.

Was „homebrew-safe-upgrade“ macht – und wie es funktioniert

homebrew-safe-upgrade fügt zwei Befehle hinzu, brew safe-upgrade und brew safe-install, die die eigentlichen Befehle umschließen. Jeder von ihnen führt denselben gate aus, bevor er an Homebrew weitergeleitet wird.

Wie homebrew-safe-upgrade ein Upgrade prüftEin brew upgrade wird vom Wrapper abgefangen, der jedes Paket auf CVEs, einen Freshness Hold und einen Bottle-SHA-Tamper-Check prüft, bevor installiert wird, und nur saubere Pakete durchlässt.brew upgradekein Security-Checksafe-upgradeCVE + Freshness+ SHA-Tamper-CheckNur sauberRiskante gehalten
Jedes Paket und seine Dependencies werden geprüft, bevor brew installiert — verwundbare, zu frische oder manipulierte werden zurückgehalten.

Es vergleicht die Zielversion mit drei Datenbanken

Jedes veraltete Paket wird anhand von OSV.dev, der GitHub Advisory Database und dem NIST NVD überprüft, wobei eine versionsbezogene Filterung zum Einsatz kommt, sodass eine alte CVE, die die von Dir tatsächlich installierte Version nicht betrifft, keinen Fehlalarm auslöst. Einwandfreie Pakete werden zum Upgrade angeboten; Pakete mit Schwachstellen werden blockiert und separat aufgelistet. (--yes führt den Vorgang unbeaufsichtigt für CI aus.)

Es überprüft die Abhängigkeiten, die mit dem Upgrade mitkommen

Das gleiche Filterverfahren wird auf die transitiven Abhängigkeiten angewendet, die die Operation in Dein System einbringen würde – sowohl brandneue als auch bereits vorhandene, deren Version aktualisiert wird –, sodass ein auf den ersten Blick einwandfreies Tool keine Schwachstelle heimlich einschleusen kann.

Ein freshness hold für brandneue Releases

Standardmäßig wird jede Formel oder jedes Cask, das vor weniger als drei Tagen veröffentlicht wurde, zurückgehalten – das ist der Zeitraum, in dem eine kompromittierte release normalerweise live ist, aber noch nirgendwo markiert wurde. Die Zurückhaltung erfolgt nach dem „Fail-Closed“-Prinzip: Wenn das Alter eines Pakets nicht überprüft werden kann (das Quell-Repo ist nicht erreichbar, GitHub begrenzt die Zugriffsrate), wird es zurückgehalten und nicht durchgelassen. Das System berücksichtigt außerdem CVE-Einträge – wenn die Version, die Du derzeit installiert hast, eine bekannte Schwachstelle aufweist, wird die Zurückhaltung des entsprechenden Patches übersprungen, sodass eine Aktualitätsregel Dich niemals von einem Sicherheitspatch abhält. Mit --min-age 0 lässt Du das deaktivieren.

Eine Manipulationsprüfung für gekaperte Wasserhähne

Das ist die Abwehrmaßnahme gegen den Angriff „Die Versionszeichenfolge sieht zwar gut aus, aber die Bytes haben sich geändert“. „homebrew-safe-upgrade“ vergleicht den SHA jeder Bottle mit dem unter formulae.brew.sh veröffentlichten kanonischen Hash und blockiert einen Tap, der unter derselben Versionsnummer eine andere Binärdatei liefert, noch bevor Homebrew ihn überhaupt installiert.

Installiere es und nutze es

Installieren

Füge den 5bats-Tap einmal hinzu und installiere dann den Wrapper:

brew install sharkyger/tap/safe-upgrade

Benutz es

brew safe-upgrade               # check every outdated package, upgrade only the clean ones
brew safe-install wget curl     # check these (and their deps) before installing
brew safe-upgrade --yes         # unattended, for CI
brew safe-upgrade --min-age 7   # stricter freshness hold

Die vollständige Liste der Flags, Hinweise zur Cask-Abdeckung und die Quelle findest Du auf GitHub: github.com/sharkyger/homebrew-safe-upgrade (MIT).

FAQ

Werden Homebrew-Pakete auf ihre Sicherheit überprüft?

Nein. Homebrew-Formeln und -Casks sind von der Community gepflegte Rezepte in öffentlichen Repos; niemand überprüft jede release auf bekannte Schwachstellen, und brew upgrade führt keine solche Überprüfung durch. homebrew-safe-upgrade fügt diese Überprüfung hinzu, bevor irgendetwas installiert wird.

Überprüft „brew upgrade“ auf Schwachstellen?

Das tut es nicht – brew upgrade fetcht die neueste Version und installiert sie, unabhängig von bekannten CVEs. brew safe-upgrade überprüft zunächst jede Zielversion und die damit verbundenen Abhängigkeiten anhand von drei Datenbanken für Schwachstellen und aktualisiert nur die einwandfreien.

Kann ein Homebrew-Hahn manipuliert werden?

Ja – ein kompromittierter Tap könnte eine andere Binärdatei unter einer Versionsnummer bereitstellen, der Du bereits vertraust. homebrew-safe-upgrade vergleicht den SHA-Wert jeder Bottle mit dem kanonischen Eintrag bei Homebrew und blockiert eine Abweichung, bevor brew sie installiert.


homebrew-safe-upgrade ist eines der 5bats supply-chain gates – dasselbe Prinzip „Prüfen, bevor es läuft“, angewendet auf Python , PHP und die Pakete, die ein KI-Assistent installiert .

Sieh Dir den Quellcode und alle Optionen auf GitHub an →