
Proof-of-Concept-Labor zur Demonstration von Command Injection bei GitHub Actions Workflow Dispatch (CVE-2026-39866). Führt verwundbare und gepatchte Versionen nebeneinander für die Bildungsanalyse aus.
Proof-of-Concept-Labor für Command Injection im GitHub-Actions-Workflow-Dispatch
CVE-2026-39866 ist ein Command-Injection-Fehler im GitHub-Actions-Release-Workflow von Lawnchair. Die Datei release_update.yml übergibt Benutzereingaben ohne Quoting direkt an bash, sodass ein Angreifer Befehle einschleusen kann. Dieses Repository führt sowohl die verwundbare als auch die gepatchte Version nebeneinander aus.
| Feld | Wert |
|---|---|
| CVE-ID | CVE-2026-39866 |
| GHSA | GHSA-9prc-pp2c-3427 |
| CWE | CWE-78 (Unzureichende Neutralisierung spezieller Elemente in einem OS-Befehl) |
| Produkt | LawnchairLauncher/lawnchair |
| Betroffen | Alle Versionen unterhalb von fcba413 |
| Gepatcht | fcba413 |
| Entdeckung | Abhay Kumar (@abhayclasher) |
Die Schwachstelle befindet sich in der Workflow-Datei release_update.yml. Die Aktion nimmt einen Parameter artifactName entgegen und übergibt ihn ohne Quoting direkt an einen bash-Befehl.
- name: Rename artifact
run: mv ${{ inputs.artifactName }}.zip lawnchair.zip
GitHub Actions ersetzt den Variablenwert in der Zeichenkette, bevor die Shell sie ausführt. Ohne Anführungszeichen um ${{ inputs.artifactName }} interpretiert die Shell Leerzeichen und Semikolons als Befehlsseparatoren.
Wenn ein Angreifer file.zip; touch pwned.txt # als artifactName liefert:
Wie GitHub Actions es parst:
${{ inputs.artifactName }} → file.zip; touch pwned.txt #
Wie die Shell es ausführt:
mv file.zip; touch pwned.txt #.zip lawnchair.zip
Die Shell führt mv file.zip aus, dann touch pwned.txt und ignoriert den Rest als Kommentar.
GITHUB_TOKEN oder Release-Signaturschlüssel).git clone https://github.com/abhayclasher/CVE-2026-39866.git
cd CVE-2026-39866/app
npm install
node server.js
git clone https://github.com/abhayclasher/CVE-2026-39866.git
cd CVE-2026-39866
docker compose up -d
Nachdem der Server gestartet ist, rufen Sie diese URLs auf:
| URL | Beschreibung |
|---|---|
http://localhost:3000/workflow/vulnerable | Verwundbarer Workflow — Command Injection wird beim Absenden ausgeführt |
http://localhost:3001/workflow/patched | Gleicher Workflow mit angewendetem fcba413-Patch |
Die verwundbare Version führt Ihren eingeschleusten Befehl auf dem Runner aus. Die gepatchte Version behandelt die Eingabe als literale Zeichenkette.
Sie können auch das eigenständige PoC ausführen:
cd poc
node exploit.js
Dies startet einen minimalen Server auf Port 3000, der denselben Fehler ohne den vollständigen Anwendungskontext demonstriert.
1. Angreifer kontrolliert den Eingabeparameter artifactName
2. GitHub Actions expandiert ${{ inputs.artifactName }} in das YAML
3. Der run-Schritt sendet dies an bash
4. Bash sieht unquotierte Sonderzeichen und behandelt sie als Befehlssyntax
5. Befehle werden mit den Privilegien der Runner-Umgebung ausgeführt
┌────────────────────────────────────────────────────┐
│ 1. Bösartige Eingabe: │
│ │
│ artifactName = "file.zip; id #" │
│ │
│ 2. GitHub Actions setzt in YAML ein: │
│ │
│ run: mv file.zip; id #.zip lawnchair.zip │
│ │
│ 3. Bash sieht: │
│ - mv file.zip │
│ - id <-- Beliebiger Befehl │
│ - #.zip lawnchair.zip (ignoriert) │
│ │
│ 4. Shell führt beliebigen Befehl aus │
└────────────────────────────────────────────────────┘
Version fcba413 führt Quoting um die interpolierte Variable ein:
- name: Rename artifact
run: mv "${{ inputs.artifactName }}.zip" lawnchair.zip
Anführungszeichen verhindern, dass die Shell Sonderzeichen parst. Die Nutzlast wird weiterhin als literale Dateinamen-Zeichenkette behandelt.
Best Practice ist die Verwendung von Umgebungsvariablen, um Benutzereingaben vollständig zu isolieren:
- name: Rename artifact
env:
ARTIFACT_NAME: ${{ inputs.artifactName }}
run: mv "$ARTIFACT_NAME.zip" lawnchair.zip
Vollständigen Commit ansehen: fcba413
CVE-2026-39866/
├── README.md # Diese Datei
├── docker-compose.yml # Docker-Labor-Konfiguration
├── app/
│ ├── Dockerfile # Container-Build-Konfiguration
│ ├── package.json # Node.js-Abhängigkeiten
│ └── server.js # Simulation des verwundbaren + gepatchten Workflow-Runners
└── poc/
└── exploit.js # Eigenständiges minimales Proof-of-Concept
Gemeldet von Abhay Kumar. Dieses Repository ist ausschließlich für lokale Bildungszwecke gedacht. Stellen Sie den verwundbaren Server nicht in einem öffentlichen Netzwerk bereit.
Nur für Bildungszwecke — nur in isolierten Umgebungen verwenden