Warum mir eine gültige Signatur 2026 nicht mehr reicht — eine ehrliche Notiz nach Mini Shai-Hulud

Am Abend des 11. Mai 2026, kurz vor 22 Uhr deutscher Zeit, ging die erste Veröffentlichung der StepSecurity-Forscher zur Mini-Shai-Hulud-Welle über meine Feeds. 42 @tanstack/*-Pakete, 84 bösartige Versionen, dazu Mistral AI, UiPath, OpenSearch, Guardrails — über 170 Pakete insgesamt, über 500 Millionen kumulative Downloads. Den technischen Befund habe ich mit Mandantenblick auf moselwal.de aufgeschrieben. Hier möchte ich kurz die eine Sache festhalten, die mich an dem ganzen Vorfall am meisten beschäftigt hat — und warum sie wichtiger ist als die hundertste Liste betroffener Versionen.
Eine Lieferung, die in jeder verifizierbaren Weise echt war
Die kompromittierten npm-Pakete tragen eine gültige SLSA Build Level 3 Provenance. Das heißt: die Sigstore-Signatur ist echt, die OIDC-Identität ist die richtige, die Build-Pipeline-Spec, gegen die signiert wurde, ist die offizielle. Wer eine cosign-Verifikation in seine Install-Stage eingebaut hat — was viele von uns in den letzten anderthalb Jahren genau aus dem Grund getan haben, um Lieferketten-Vorfälle zu erkennen — hätte die kompromittierten Versionen als legitim durchgewunken. Die Verifikation ist nicht kaputt. Sie tut, was sie spezifiziert ist zu tun. Sie prüft die Schale, nicht den Inhalt.
Ich finde das einen ehrlich gemachten strukturellen Befund, und ich finde ihn deutlich unangenehmer als jede klassische Token-Diebstahl-Geschichte. Bei den Vorgänger-Vorfällen — Bitwarden-CLI im April, Aqua-Trivy im März, der ursprüngliche Shai-Hulud-Wurm im Sommer 2025 — war das Modell „Angreifer kommt an Credentials, veröffentlicht unter fremder Identität, Provenance fehlt oder ist gefälscht“. Die Antwort war jeweils: „Lass die Provenance prüfen“. Diesmal ist die Provenance nicht das fehlende oder gefälschte Stück, sondern das richtig erzeugte. Der Wurm hat die Build-Pipeline selbst entführt, im laufenden Workflow-Schritt, mit dem OIDC-Token des legitimen Maintainers — und Sigstore hat über diese Identität korrekt signiert, weil aus der Sicht der Plattform alles in Ordnung war.
Wer das nüchtern liest, sieht: „Lass die Provenance prüfen“ ist 2026 keine vollständige Antwort mehr.
Was das für meine eigene Praxis bedeutet
In den letzten 18 Stunden habe ich in den Pipelines, die ich aktiv betreibe — bei Moselwal, bei OnlyOle, in den Mandantenprojekten — den Schalter umgelegt, der seit einigen Monaten in der Schublade lag. Es sind drei Disziplinen, und ich schreibe sie hier auf, weil ich sie morgen früh in einer Mandanten-Architektur-Besprechung ohnehin erklären werde und das eigene Aufschreiben mir hilft, sie sauber zu formulieren.
Erstens: Signatur und Manifest werden getrennt geprüft. Die cosign-Verifikation bleibt am Eintritts-Gate, weil sie strukturell sauber ist und im Normalfall genau das tut, was sie soll. Direkt danach kommt eine Manifest-Diff-Stage, die jede neu aufgelöste Paket-Version gegen die unmittelbar vorhergehende Version vergleicht — nicht den Tarball als Ganzes, sondern strukturierte Felder des Pakets: scripts.postinstall, scripts.preinstall, bin-Definitionen, die Datei-Liste, neu hinzugekommene Top-Level-Dependencies. Eine Versions-Erhöhung kann legitime Änderungen in diesen Feldern haben; eine unerwartete Erweiterung der Install-Hooks ist ein hartes Signal. Die Stage ist ein paar Dutzend Zeilen Bash und jq, sie läuft in unter 200 ms pro Paket und sie produziert Build-Stops, keine stillen Warnungen.
Zweitens: Install-Hooks laufen in einem ausgehärteten Subprozess, dessen Netzwerk-Egress monitoriert ist.npm install läuft bei uns nicht mehr in derselben Shell wie der eigentliche Build, sondern in einem --ignore-scripts-Vorlauf gefolgt von einem isolierten Hook-Runner, der die Install-Hooks ein Paket nach dem anderen mit Falco-Detection im Beobachtungsfeld ausführt. Wer aus einem Install-Hook eine ausgehende Verbindung zu einer nicht-allowlisted IP aufmacht, bricht den Build ab. In den ersten 24 Stunden Realbetrieb hat das auf unseren Build-Servern zwei legitime npm-Telemetry-Pings als False Positives gefangen, die ich jetzt explizit in der Allowlist habe, und null bösartige Aktivität. Aber wenn der nächste Wurm kommt, fängt es ihn unabhängig von der Provenance-Frage.
Drittens: pull_request_target ist bei uns nur noch für Schritte erlaubt, die explizit keinen Code aus dem PR ausführen. Label-Verarbeitung, Comment-Triggers, Status-API-Updates — gerne. actions/checkout@v4 mit ref: pull_request.head.sha plus npm install im selben Job — nicht mehr. Die operative Konsequenz ist, dass wir bestimmte Preview-Build-Pipelines neu gedacht haben: der Preview-Build läuft jetzt über einen nachgelagerten workflow_run-Trigger mit Approval-Stufe. Das ist unbequemer als vorher, und das ist genau der Punkt — die Unbequemlichkeit ist der Preis, den die Sicherheit dieser Klasse verlangt.
Warum mir das alles bleibt
Ich glaube, der 11. Mai 2026 ist in zwei Jahren das Datum, das man rückblickend als Wendepunkt benennen wird — nicht weil Mini Shai-Hulud der grösste Vorfall war, sondern weil er der erste war, in dem die strukturelle Annahme „validiert-signiert heißt inhaltlich-vertrauenswürdig“ öffentlich und dokumentiert gebrochen wurde. Wer 2026 weiterhin in der Architektur lebt, in der eine Sigstore-Validierung die alleinige Eintritts-Kontrolle ist, lebt nicht mehr im Vorfeld der nächsten Welle. Er lebt in einer Architektur, die ihren Bruch bereits hinter sich hat.
Das ist keine Aufforderung zur Panik. Es ist eine Aufforderung, die zweite Stufe einzubauen. Die Provenance-Validierung bleibt richtig. Sie reicht nur nicht mehr allein.
Eine ehrliche Notiz, weil ich glaube, dass wir in den nächsten Monaten viele solcher Notizen lesen werden. Wer das jetzt einbaut, fängt die nächste Welle dieser Klasse mit. Wer auf den nächsten Patch wartet, wartet auf das falsche Werkzeug.
Mehr zur konkreten Lücke, zu den betroffenen Paketen und zu den operativen Sofortmaßnahmen für Mandanten: CVE-2026-45321 und Mini Shai-Hulud auf moselwal.de.