senn-techsenn-tech
Security
Security2026-09-29· Von Franz Senn

Plugin4Shell: Der Commit-Hash-Pin schützt nicht, wenn der Branch wie ein Hash aussieht

Coding-Agenten installieren Erweiterungen, Marktplätze heißen die Kataloge, und der empfohlene Schutz gegen gekaperte Plugin-Repos ist der Pin auf eine Commit-ID statt auf einen Branch. Genau an diesem Pin setzt Plugin4Shell an, die Air Security am 18. September 2026 veröffentlicht und die am 21. September durch The Hacker News breit gelaufen ist. Der Mechanismus in einem Satz: Der Agent soll einen Commit auschecken, der String sieht aus wie ein Hash, und auf einem Git-Host, der solche Namen als Branch oder Tag erlaubt, gewinnt der Name gegen das Objekt. Der Nutzer sieht einen Checkout, dessen Referenz formal dem Pin entspricht, der Inhalt aber dem Angreifer gehört. Zero-Click, weil der normale Installationspfad dafür reicht.

Wo der Hebel sitzt, und wo nicht

Die Auflösung von Ref-Namen vor Objekt-IDs ist kein Bug von git, sie ist dokumentiertes Verhalten: git checkout 3f2a... heißt zuerst „gibt es einen Ref, der so heißt?", und erst wenn nein, „gibt es ein Objekt, das so heißt?". Der Angriff ist deshalb host-abhängig. GitHub lehnt Branch-Namen in voller Hash-Länge über seine Namensregeln ab, dort funktioniert die Variante nicht. Bitbucket und beliebige selbst betriebene Git-Server tun das nicht per Default, und dort sitzt die Klasse. Die Gemini-CLI wurde in der Meldung über einen Branch namens FETCH_HEAD erwischt, derselbe Mechanismus mit einem Namen, den git selbst reserviert.

Der Gegencheck, den The Hacker News zur Meldung mitliefert, gehört genauso dazugeschrieben: Die ausgelieferten Marktplätze der Agenten zeigen auf GitHub-Repos, Auto-Update ist standardmäßig nur bei diesen eingebauten Marktplätzen aktiv. Wer ausschließlich davon installiert, ist von der Branch-Variante nach Darstellung von Air Security und GitHub nicht betroffen. Relevant wird es bei eigenen Marktplätzen, bei Mirror-Repos und bei jedem Setup, das Plugins aus selbst betriebenen Quellen zieht.

Was ihr nachprüfen könnt, ohne irgendetwas zu glauben

  1. Versionen messen statt Branchenfolklore. claude --version und codex --version, die Schwellen aus der Meldung sind 2.1.179 und 0.146.0. Ein Versionsstand, den ihr nicht abgelesen habt, ist kein Nachweis.
  2. Der eigene Git-Server als Scope: Prüft, ob euer Host Ref-Namen in Hash-Form annimmt. Bei einem selbst betriebenen Server ist die Antwort fast immer ja, und ein einziger Pre-Receive-Hook, der Refs in 40-Zeichen-Hex-Form ablehnt, schließt die Tür für die ganze Flotte.
  3. Installation heißt, das Objekt zu prüfen: Nach dem Checkout sollte git cat-file -t HEAD ein commit liefern und die IDs müssen verglichen werden, sonst ist der Pin ein Textvergleich gegen eine Zeichenkette, die der Gegenüber selbst geschrieben hat.
  4. Marktplatz-Referenzen lesen: Die marketplace.json-Dateien nennen URLs. Steht dort eine Quelle, die ihr nicht kontrolliert und deren Namensregeln ihr nicht kennt, ist das der Ort, an dem die Klasse greift.

Was an der Meldung Unsicherheit bleibt

Die Versionsnummern der Patches stammen aus einem Presseartikel statt aus Security-Advisories; bei dreien der vier Agenten (Copilot, Gemini CLI ohne Fix, Claude Code ohne separaten Advisory-Text) ist der Stand damit weniger belastbar als bei einem Vendor-Meldungsweg. Air Security hat den Mechanismus demonstriert, eine eigene Nachbau-Bestätigung von außen stand zum Mitnahmestand aus. Und der Begriff „Zero-Click" beschreibt den Installationspfad, nicht die ganze Welt: Er setzt voraus, dass der Agent Plugins aus einer angreifbaren Quelle zieht. Für Setups, die das nicht tun, ist die Meldung eine Erklärung, warum der Hash-Pin eine Namensregel-Voraussetzung hat. Für alle anderen ist es eine halbe Stunde Arbeit an Pre-Receive-Hooks und Versionschecks.

Weiterführende Quellen

Fragen?
Ist der Pin auf einen Commit-Hash damit wertlos?+

Nein, aber er ist nur so stark wie die Namensregeln des Git-Hosts. git prüft beim Auschecken zuerst, ob der String als Ref-Name existiert, erst danach als Objekt. Ein Branch mit dem Namen eines 40-Zeichen-Hashes gewinnt diese Reihenfolge. GitHub verbaut sich den Trick selbst über seine Namensregeln, ein Git-Server, den ihr selbst betreibt, tut das nicht automatisch.

Welche Versionen sind gepatcht?+

Nach der Meldung von The Hacker News: Claude Code ab 2.1.179, OpenAI Codex ab 0.146.0. Für GitHub Copilot war zum Zeitpunkt der Meldung kein Fix da, die Gemini-CLI-Variante über einen Branch namens FETCH_HEAD lässt Google ungepatcht. Alle vier Versionsangaben stammen aus einem Pressebericht statt aus Sicherheitsmeldungen der Hersteller, das ist mit Stand 29.09.2026 so dazusagen.

Gibt es Angriffe aus der Wildbahn?+

Nach dem Stand der Meldung: nein. Bis zum 18.09.2026 gab es kein CVE und keinen Hersteller-Advisory zu diesem Mechanismus, und kein Hinweis auf reale Ausnutzung war sichtbar. Die Meldung beschreibt einen Mechanismus; eine laufende Kampagne war nicht zu sehen.