Hoch

Wenn der Image-Bauer den falschen Brief annimmt: drei Lücken in apko (CVE-2026-42574 / -42575 / -42576) und was Wolfi-Build-Pipelines heute brauchen

Hölzerner Setzkasten mit präzisem Raster aus Edelstahl-Würfeln auf glattem Beton; in drei Fächern stehen leicht abweichende Messing-Würfel gleicher Größe als stille Substitution. Daneben eine Kraftpapier-Etikette mit oxblutfarbenem Faden und eine messingfarbene Juwelierlupe im kühlen Nordlicht.

Am 9. Mai 2026 hat Chainguard drei Sicherheitslücken in apko veröffentlicht — dem Werkzeug, das in Wolfi-basierten Pipelines aus deklarativen YAML-Dateien OCI-Container-Images baut, ohne Dockerfile, ohne Layering-Tricks, ohne Build-Container. Drei Lücken, die alle an einer Stelle ansetzen, die viele Bauer-Hersteller stillschweigend für vertrauenswürdig halten: dem Übergang zwischen einem signierten APK-Index und der einzelnen .apk-Datei, die anschließend in das Image hineingezogen wird.

Was hat sich geändert? Pfad-Traversal über Symlink-Tar-Einträge (CVE-2026-42574, Fix 1.2.5), fehlender Hash-Vergleich einzelner .apk gegen den signierten Index (CVE-2026-42575, Fix 1.2.7) und ein Type-Assert-Panic auf Nicht-RSA-JWKS-Schlüssel (CVE-2026-42576, Fix 1.2.7). Wer ist betroffen? Jede Pipeline, die apko in einer Version >=0.14.8 und <1.2.7 ausführt — also faktisch jeder, der Wolfi-Images selbst baut. Was sollten Sie heute lesen? Patch-Pfad auf 1.2.7, SBOM-Diff-Stage als strukturelle Antwort, Detection auf Build-Hosts — in dieser Reihenfolge.

Zusammenfassung in 90 Sekunden

Am 9. Mai 2026 hat Chainguard drei Lücken in apko veröffentlicht. CVE-2026-42574 (Path Traversal): eine präparierte .apk kann einen TypeSymlink-Tar-Eintrag installieren, dessen Ziel außerhalb des Build-Roots liegt; ein nachfolgender Verzeichnis- oder Datei-Eintrag wandert den Symlink durch und beschreibt Host-Pfade. Fix in apko 1.2.5.

CVE-2026-42575 (Insufficient Verification of Data Authenticity) ist die strukturell unangenehmere: apko prüft die Signatur über APKINDEX.tar.gz, gleicht aber niemals die einzelne heruntergeladene .apk gegen die im signierten Index hinterlegte Prüfsumme ab. Wer Download-Antworten substituieren kann — kompromittierter Mirror, HTTP-Repository, vergiftete CDN-Cache-Antwort — schiebt beliebige Pakete in das gebaute Image. Fix in apko 1.2.7.

CVE-2026-42576 (Incorrect Type Conversion): DiscoverKeys in pkg/apk/apk/implementation.go führt einen Type-Assert von JWKS-Schlüsseln auf *rsa.PublicKey durch, ohne den Key-Typ vorher zu prüfen. Ein JWKS-Endpunkt, der einen EC-Schlüssel zurückgibt, lässt apko panicen. Build bricht ab. Fix in apko 1.2.7.

Empfehlung: Pin direkt auf 1.2.7 (oder höher), Pipeline-Cache invalidieren, SBOM-Diff-Stage zwischen apko build und apko publish als strukturelle Antwort gegen 42575, Falco- oder Tetragon-Regel auf Build-Hosts gegen 42574. Backend-API-Keys in der Build-Pipeline rotieren, wenn ein Verdachtszeitraum besteht.

Was die drei Lücken technisch sind — und wer betroffen ist

Die strukturelle Linie hinter allen dreien

apko prüft die äußere Hülle, nicht den einzelnen Inhalt. Der signierte APKINDEX.tar.gz wird verifiziert, weil das Wolfi-Modell genau dort Vertrauen verankert. Aber der Sprung vom verifizierten Index zur konkreten .apk ist genau die Stelle, an der das Vertrauensmodell zerfällt.

42574 zeigt das im Dateisystem-Layout: ein Tar-Archiv darf in apko Symlinks setzen, und nichts in der dirFS-Abstraktion zwingt anschließende Schreiboperationen, das Symlink-Ziel auf Containment innerhalb des Build-Roots zu prüfen. Wer in einer früheren apko-Version (vor 1.1.1, im Februar dieses Jahres mit GHSA-5g94-c2wx-8pxw geschlossen) gepatcht und dann das Thema abgeräumt hat, sieht in 42574 die nächste Iteration derselben strukturellen Klasse.

42575 ist der eigentliche Stachel. Das Wolfi-Repository-Modell signiert den Index — die Liste der verfügbaren Pakete mit ihren Versionen und Hashes. Die einzelne .apk wird über HTTPS heruntergeladen, und ihre Authentizität ergibt sich (sollte sich ergeben) aus dem Vergleich ihres berechneten Control-Hashs gegen den im signierten Index hinterlegten Hash. Genau dieser Vergleich fehlt in getPackageImpl() in den Versionen vor 1.2.7. Der Index sagt „Paket X soll diesen Hash haben“, die heruntergeladene Datei hat einen anderen Hash, und apko schiebt sie trotzdem ins Image.

42576 ist das schlichteste und didaktisch das nützlichste Stück: ein unbedingter Type-Assert ohne vorherige Type-Prüfung. Sobald ein JWKS-Anbieter auf EC oder Ed25519 umstellt — was aus kryptographischer Hygiene wünschenswert ist —, fällt apko um. Kein RCE, kein Datenleck, aber ein Verfügbarkeits-Problem in einer Pipeline, die per Definition nachts ohne Aufsicht laufen soll.

Wer ist betroffen

Direkt betroffen ist jede Pipeline, die apko in einer Version >=0.14.8 und <1.2.5 (für 42574) bzw. <1.2.7 (für 42575 und 42576) ausführt. Wer Chainguard-Images aus dem Public Catalog konsumiert, ist nicht direkt betroffen — Chainguard baut diese Images mit aktuellem apko in der eigenen Pipeline. Wer selbst Wolfi-Images baut — direkt mit apko, indirekt über melange plus apko, über Bazel-Regeln (rules_apko) oder über CI-eigene Wrapper — ist direkt betroffen, sofern die ausgeführte apko-Binary älter als 1.2.7 ist. Wer APKO als Library in eigene Go-Programme einbindet, muss prüfen, ob die Programmsuite mit aktuellen apko-Modulen gebaut wurde — das ist ein go.sum-Audit, nicht ein einfaches Binary-Update.

Mitigation und Sofortmaßnahmen

Die saubere Reihenfolge ist: erstens Versionsprüfung in der Pipeline (apko version); zweitens auf 1.2.7 oder höher anheben (docker pull cgr.dev/chainguard/apko:latest oder go install chainguard.dev/apko@v1.2.7); drittens Pipeline-Cache invalidieren — keine alten apko-Binaries in CI-Cache-Layern stehen lassen.

Für Bazel-Builds mit rules_apko: Die Regeln binden eine bestimmte apko-Version ein, deren Pin im MODULE.bazel oder WORKSPACE aktualisiert werden muss. bazel mod tidy allein zieht das nicht nach. Für HTTP-Mirrors als Übergangslösung: TLS-Umzug und Konfigurations-Verifikation, sofern 1.2.7 nicht sofort in Bazel-Pins eingebaut werden kann.

Detection und Prüfung

Pipeline-Inventur: Welche apko-Versionen laufen tatsächlich in welchen Build-Jobs? Ein grep-Audit über GitHub-Actions-Workflows findet die meisten direkten Aufrufe; eine SBOM-Generierung über die Build-Container findet die indirekt eingebetteten Versionen. Image-SBOM gegen Index abgleichen: Für 42575 ist die robusteste Detection eine SBOM-Inventur des gebauten Images, die jede .apk mit ihrem Hash gegen den Wolfi-Index zum Build-Zeitpunkt vergleicht. Ein Mismatch ist der Beweis einer Substitution. Falco-Regel oder Tetragon-TracingPolicy auf den Build-Hosts: Wer apko in einer ephemeren Build-Umgebung ausführt, kann Schreibzugriffe außerhalb des erwarteten Build-Roots als Indikator für 42574 instrumentieren.

Betreiberempfehlung

Sofort patchen, wenn Sie in den letzten 7 Tagen Wolfi-Images mit eigener apko-Version (<1.2.7) gebaut und in eine produktiv genutzte Registry gepusht haben. Wartungsfenster akzeptabel, wenn Sie apko nur in nächtlichen Rebuilds verwenden, deren Output erst nach manueller Approval-Stufe in Produktion läuft. Reine Konsumenten-Position, wenn Sie ausschließlich cgr.dev/chainguard/*-Images aus dem Public Catalog ziehen — dort ist der Fix in der Anbieter-Pipeline bereits eingespielt.

Mittelständische DevOps-Teams, die TYPO3-, Sylius- oder Symfony-Workloads in Wolfi-Images verpacken, haben in den meisten Fällen genau einen apko-Aufruf in der CI-Pipeline. Update der Pipeline-Image-Version auf cgr.dev/chainguard/apko:1.2.7, CI-Cache invalidieren, eine Test-Build-Stufe auf einem Feature-Branch laufen lassen — die Übung dauert 30 Minuten. Wer nightly rebuilds fährt, sieht das Update in der nächsten Nachtcharge. Größere Organisationen mit Bazel- oder Pulumi-basiertem Image-Definitionssatz brauchen ein zweistufiges Vorgehen: erst die Pin-Liste auf 1.2.7 hochziehen und in einem isolierten Replikations-Build verifizieren, dass die produzierten Images identisch sind; dann die Pin-Aktualisierung als Standard-Release-Prozess durch die normalen Quality-Gates schicken. Deklarative Build-Hosts (NixOS, Talos, Flatcar) schließen einen großen Teil des 42574-Risikos automatisch aus, weil der Build-Root strukturell isoliert wird; 42575 und 42576 betreffen sie unverändert.

Was wir konkret getan haben

Wir haben am 9. Mai um 18:30 nach der Disclosure den apko-Pin in unserer eigenen Image-Pipeline aktualisiert und einen Replikations-Build der letzten drei Wochen Wolfi-Image-Tags durchgeführt. Diff der Image-SBOMs gegen die zuvor produzierten Tags: identisch bis auf das Build-Timestamp-Feld. Das war für uns die Validierung, dass die Pipeline-Aktualisierung keine inhaltlichen Verschiebungen einführt.

Parallel haben wir eine SBOM-Diff-Stage in die nächtliche Build-Pipeline eingezogen, die jede neu gebaute .apk-Aufnahme gegen den signierten Wolfi-Index abgleicht. Das schließt 42575 strukturell, unabhängig davon, ob die unterliegende apko-Binary noch eine ungepatchte Version verwendet. Detection-seitig haben wir eine Falco-Regel auf unseren Build-Hosts scharfgeschaltet, die Schreibzugriffe außerhalb des konfigurierten Build-Roots als Indikator für 42574 markiert.

Technischer Deep Dive

Die strukturelle Frage hinter 42575 lohnt sich genauer anzusehen. Das Wolfi-Modell verankert Vertrauen in einer signierten Index-Datei, weil das die einzige Stelle ist, an der Chainguard kryptographisches Material kontrolliert. Die einzelnen .apk-Dateien werden über CDN-Endpunkte ausgeliefert, deren Integrität sich aus der TLS-Verbindung plus dem nachgelagerten Hash-Vergleich gegen den Index ergeben sollte. Genau dieser zweite Schritt fehlte in getPackageImpl(). Der Code-Pfad parst den Hash, hält ihn als ChecksumString() bereit, berechnet den tatsächlichen Hash der heruntergeladenen Datei — und vergleicht die beiden Werte nie.

Der Fix in 1.2.7 ist die naheliegende Zeile: if actualHash != expectedHash { return ErrChecksumMismatch }. Das ist die Sorte von Fehler, die in einem Codereview hätte auffallen sollen — und die deshalb als Lehre interessant ist: nicht weil sie neuartig wäre, sondern weil sie zeigt, dass auch ein hochsicherheitsorientiertes Projekt mit klarem Threat Model an genau dieser Stelle eine Lücke hatte. Eine Vertrauenskette zerfällt nicht an exotischer Kryptographie, sondern an der vergessenen Vergleichszeile zwischen zwei korrekt berechneten Werten.

42574 hat eine ähnliche didaktische Klarheit: dirFS als Abstraktion soll genau das verhindern, was 42574 ermöglicht — Schreiben außerhalb des Roots. Aber MkdirAll und Symlink ohne Containment-Prüfung in den Pfad-Operationen lassen die Abstraktion an genau der Stelle leck werden, an der sie schützen sollte. Jede Filesystem-Abstraktion, die Symlinks zulässt und gleichzeitig Containment verspricht, muss diese Symlinks vor jeder Operation auflösen.

Fazit

apko ist eine bemerkenswert klare und gut auditierbare Code-Basis. Dass drei Lücken auf einmal kommen, ist kein Zeichen schlechter Qualität, sondern eines aktiv geprüften Projekts: 42574 setzt eine Linie fort, die mit GHSA-5g94-c2wx-8pxw im Februar dieses Jahres begonnen hat; 42575 ist die Sorte struktureller Verifikations-Lücke, die in jedem Lieferketten-Werkzeug erscheinen kann; 42576 ist die Sorte Type-Assertion-Panic, die sich in jeder Go-Codebase findet, sobald jemand die Eingabe variiert.

Die Frage lautet nicht, ob apko ein vertrauenswürdiges Werkzeug ist. Sie lautet, ob Sie die zweite Vertrauensstufe — den Vergleich der einzelnen Komponente gegen den signierten Index — in Ihrer eigenen Pipeline rekonstruieren oder darauf vertrauen, dass das Werkzeug es vollständig und ausnahmslos für Sie tut. Diese Woche haben wir gesehen, dass es das nicht immer tut. Die strukturelle Antwort ist eine eigene Verifikations-Stage, nicht der nächste Patch.

Persönlicher Hintergrund und technische Details zur Härtung von Wolfi-Build-Pipelines: ole-hartwig.eu.

Häufige Fragen zu apko CVE-2026-42574 / -42575 / -42576

Wir konsumieren Chainguard-Images aus dem öffentlichen Katalog — betrifft uns das?+

Direkt nein. Chainguard baut die cgr.dev/chainguard/*-Images mit aktuellem apko in der eigenen Pipeline; die Bilder im öffentlichen Katalog sind nicht betroffen. Wer reiner Consumer ist, sitzt strukturell gut.

Wir nutzen melange und apko nur über Bazel-Regeln — was patchen wir genau?+

Den apko-Pin im MODULE.bazel (oder WORKSPACE) auf v1.2.7 heben und bazel mod tidy laufen lassen. Bazel-Regeln pinnen eine apko-Version, die nicht automatisch mitgezogen wird — daher ist das ein expliziter Pin-Update-Schritt.

Warum eine SBOM-Diff-Stage, wenn 1.2.7 die 42575 ohnehin schließt?+

Weil die nächste vergleichbare Lücke kommt. Die strukturelle Schwäche — Verifikation der einzelnen Komponente gegen das signierte Index — ist eine Klasse, die in jedem Supply-Chain-Tool auftauchen kann. Eine eigene Hash-Verifikations-Stage zwischen Build und Publish schützt unabhängig davon, ob der nächste Patch rechtzeitig kommt.

Ist 42574 nur relevant, wenn wir die .apk-Quelle selbst kontrollieren?+

Nein — die Lücke wirkt auf jede .apk, die der apko-Build verarbeitet. Sobald Sie aus dem Wolfi-Repository oder einem eigenen Mirror Pakete ziehen, ohne deren Inhalt vorher selbst geprüft zu haben, ist der Angriffsweg offen. Die Containment-Eigenschaft der dirFS-Abstraktion deckt das in Versionen vor 1.2.5 nicht ab.

Wir nutzen HTTP-Mirror für Wolfi — wie dringend ist der Wechsel auf HTTPS?+

Heute. HTTP-Mirror geben jedem MitM-Angreifer im Pfad die Möglichkeit, Download-Responses zu substituieren — was bei aktivierter 42575 ohne Hash-Verifikation direkt zur Paket-Substitution wird. Wechsel auf HTTPS ist Mindestanforderung; SBOM-Diff-Stage ist die strukturelle Ergänzung.

Wir hatten GHSA-5g94-c2wx-8pxw im Februar geschlossen — ist 42574 neu?+

Ja, 42574 ist eine eigene, neu entdeckte Variante derselben Klasse. Die Februar-Lücke wurde mit apko 1.1.1 geschlossen; 42574 betrifft Versionen ab 0.14.8 und ist erst in 1.2.5 vollständig adressiert. Das zeigt, dass die Containment-Schicht in der dirFS-Abstraktion strukturell exponiert bleibt — daher der Hinweis auf eine eigene Detection-Regel auf den Build-Hosts.

Bevor das nächste apko-CVE in den Bau-Output rutscht — sprechen wir über die Verifikations-Stage.

Wir prüfen, mitigieren und validieren Ihre Wolfi-Build-Pipeline gegen apko CVE-2026-42574 / -42575 / -42576 — inklusive SBOM-Diff-Stage und Build-Host-Detection

SBOM-Inventur des bestehenden Image-Bestands, Stopgap-Rollout des apko-Pins auf 1.2.7, Einbau einer Hash-Verifikations-Stage zwischen Build und Publish, PoC-Validierung der Falco- oder Tetragon-Detection auf Ihren Build-Hosts — in dieser Reihenfolge, mit dokumentiertem Stand pro Schritt.

Das ist die operative Routine aus DevSecOps as a Service und unserer Standard-Linie für Lieferketten-Härtung. Wenn Sie Wolfi-Images selbst bauen — als Eigenleistung im DACH-Mittelstand, im Plattformbetrieb für mehrere Mandanten oder als CI-eigener Wrapper um melange/apko — sprechen wir vor dem nächsten produktiven Push.

Termin direkt vereinbaren