Der Cloud-Security-Anbieter Sysdig erläutert in einer aktuellen Analyse, wie Bedrohungsakteure Self-Hosted GitHub Actions Runner missbrauchen, um dauerhaften Remote-Zugriff aufzubauen. Der Shai-Hulud-Wurm ist ein reales Beispiel. Er demonstrierte am 24. November 2025 genau diese Technik im großen Maßstab. Rogue Runner werden installiert und diese nutzen verwundbare Workflows als Command-and-Control (C2)-Kanal. Das geschieht bei Traffic, der wie normale GitHub-Nutzung aussieht.
Self-hosted Runner laufen auf der Infrastruktur der Organisation (Server/Cloud-Instanzen) und bieten dadurch oft Zugriff auf interne Netze und potenziell „gecachte Secrets/Credentials“. Zudem führen sie per Design beliebigen Workflow-Code aus. Hinzu kommt, dass das Onboarding bewusst „low friction“ ist: Mit ./config.sh und einem Registrierungstoken entsteht eine langfristige Verbindung zu GitHub. Solche Tokens können (mit Admin-Rechten) auch über die GitHub-API erzeugt werden.
Fallstudie: Shai-Hulud als Backdoor über Rogue Runner
Sysdig beschreibt, wie Shai-Hulud nach einer initialen Kompromittierung (u. a. über trojanisierte NPM-Pakete) GitHub so ausnutzt, dass ein kompromittiertes System praktisch „von innen heraus“ an die GitHub-Infrastruktur angebunden wird: Die Malware legt ein neues öffentliches Repository mit einem festen Marker in der Beschreibung an und aktiviert bewusst nur „Discussions“ als späteren Kommunikationskanal. Anschließend beschafft die Malware per GitHub-API ein Runner-Registration-Token, installiert den offiziellen GitHub-Actions-Runner versteckt (z. B. in ~/.dev-env), startet ihn persistent im Hintergrund (z. B. via nohup) und hebt Schutzmechanismen aus, indem der Runner explizit mit Root-Rechten laufen darf (RUNNER_ALLOW_RUNASROOT=1).
Der eigentliche „Backdoor“-Mechanismus entsteht durch einen absichtlich verwundbaren Workflow (z. B. discussion.yaml), der den Text einer „Discussion“ direkt in einen run-Befehl übernimmt. Durch Shell-Metazeichen lässt sich so Command Injection auslösen: Angreifer posten eine „Discussion“, und der Runner führt die eingeschleusten Befehle aus. Um darüber hinaus Persistenz über Job-Enden hinweg zu erreichen, wird RUNNER_TRACKING_ID manipuliert (z. B. 0), sodass GitHub Prozesse nicht wie vorgesehen bereinigt.
Breitere Risikomuster: Es geht nicht nur um „Discussions“
Die Analyse macht deutlich: Entscheidend ist nicht der konkrete Trigger, sondern „untrusted“ Input, der auf persistenten self-hosted Runnern verarbeitet wird. Beispiele für besonders riskante Trigger-/Konfigurationsmuster sind:
- pull_request_target: läuft im Kontext des Base-Repos – mit potenziell privilegiertem Token- und Secret-Zugriff, wenn Workflows PR-Code auschecken/ausführen.
- issue_comment: Kommentare in öffentlichen Repos sind ein naheliegender Injektionsvektor, wenn Text ohne Sanitization verarbeitet wird.
- „Neglected“ Activity Types: wenn Events nicht granular über „types“ eingeschränkt werden, können Angreifer Workflows über weniger auffällige Aktionen triggern (z. B. Labeln von Issues oder „unanswering“ einer „Discussion“).
- Persistenter Systemdienst: Angreifer können Runner zudem als Service konfigurieren (z. B. via ./svc.sh), um Reboots zu überstehen und unauffälliger als „normaler“ Dienst (systemd) zu laufen.
Schritte zur Behebung des Problems
Um Rogue Runner und persistente Bedrohungen zu erkennen, lohnt es sich, gezielt nach entsprechenden Signalen zu suchen. Ein besonders starkes Indiz ist die Variable RUNNER_TRACKING_ID=0, da diese typischerweise dazu dient, den üblichen Prozess-Cleanup nach Job-Ende zu umgehen. Zusätzlich sollte das Runner-Inventar regelmäßig geprüft werden, wobei auch die Fragen zu klären sind, wann und von wem Runner registriert wurden. Solche Registrierungen lassen sich über Audit-Log-Events wie „repo.register_self_hosted_runner” nachvollziehen. Weitere Hinweise können von Runner-Prozessen aus versteckten Verzeichnissen (z. B. ~/.dev-env) sowie von auffälligen Runner-Namen, unerwarteten Outbound-Verbindungen von Runner-Prozessen zu bislang unbekannten Repositories und von Workflow-Dateien geliefert werden, in denen „untrusted“ Input über unsaubere Expression-Interpolation direkt in Run-Befehle einfließt.
Zur Härtung und Eindämmung bieten sich klare präventive Maßnahmen an: Self-Hosted-Runner sollten nicht in öffentlichen Repositories eingesetzt werden. Wo möglich, sind ephemere Runner sinnvoll, bei denen die Umgebung nach jedem Job wieder verworfen wird. Auch wenn das keine „Single-Job“-Garantie bedeutet, erhöht es die Hürde deutlich. Außerdem sollte der Einsatz über Runner Groups mit Repository-Restriktionen strikt segmentiert werden, sodass nur klar definierte Repositories bestimmte Runner nutzen dürfen. Um das Risiko weiter zu senken, sollten auf Runner-Systemen grundsätzlich keine sensiblen Daten wie Secrets, SSH-Schlüssel oder API-Token gespeichert werden, da Workflow-Auslöser im Zweifel Zugriff auf die Runner-Umgebung haben könnten. Schließlich ist es ratsam, die Netzwerkzugriffe von Runnern stark zu begrenzen und insbesondere Zugriffe auf Metadaten-Services, Produktionsdatenbanken oder andere kritische interne Ziele zu verhindern.
Fazit
Self-hosted Runner sind eine unterschätzte Angriffsfläche: Sie führen per Design Workflow-Code aus, halten persistente Verbindungen zu GitHub und laufen häufig mit weitreichenden Berechtigungen. Der Shai-Hulud-Fall zeigt, wie Angreifer diese Eigenschaften schnell nutzen können, um Backdoors zu etablieren, die im normalen CI/CD-Traffic untergehen.



