
प्रूफ-ऑफ-कॉन्सेप्ट लैब जो GitHub Actions वर्कफ़्लो डिस्पैच में कमांड इंजेक्शन (CVE-2026-39866) का प्रदर्शन करती है। शैक्षिक विश्लेषण के लिए कमज़ोर और पैच किए गए संस्करणों को साथ-साथ चलाती है।
GitHub Actions वर्कफ़्लो डिस्पैच में कमांड इंजेक्शन के लिए प्रूफ-ऑफ-कॉन्सेप्ट लैब
CVE-2026-39866 Lawnchair के GitHub Actions रिलीज़ वर्कफ़्लो में एक कमांड इंजेक्शन बग है। release_update.yml फ़ाइल उपयोगकर्ता इनपुट को बिना कोटेशन के सीधे bash में पास करती है, इसलिए एक हमलावर कमांड इंजेक्ट कर सकता है। यह रिपॉज़िटरी कमज़ोर और पैच किए गए दोनों संस्करणों को साथ-साथ चलाती है।
| फ़ील्ड | मान |
|---|---|
| CVE ID | CVE-2026-39866 |
| GHSA | GHSA-9prc-pp2c-3427 |
| CWE | CWE-78 (OS कमांड में प्रयुक्त विशेष तत्वों का अनुचित न्यूट्रलाइज़ेशन) |
| उत्पाद | LawnchairLauncher/lawnchair |
| प्रभावित | fcba413 से नीचे के सभी संस्करण |
| पैच किया गया | fcba413 |
| खोज | अभय कुमार (@abhayclasher) |
यह भेद्यता release_update.yml वर्कफ़्लो फ़ाइल में मौजूद है। एक्शन एक artifactName पैरामीटर लेता है और उसे बिना कोटेशन के सीधे bash कमांड में पास करता है।
- name: Rename artifact
run: mv ${{ inputs.artifactName }}.zip lawnchair.zip
GitHub Actions शेल चलाने से पहले स्ट्रिंग में वेरिएबल मान को प्रतिस्थापित करता है। ${{ inputs.artifactName }} के आसपास कोटेशन के बिना, शेल रिक्त स्थान और सेमीकोलन को कमांड विभाजक के रूप में व्याख्या करता है।
यदि कोई हमलावर artifactName के रूप में file.zip; touch pwned.txt # प्रदान करता है:
GitHub Actions इसे कैसे पार्स करता है:
${{ inputs.artifactName }} → file.zip; touch pwned.txt #
शेल इसे कैसे निष्पादित करता है:
mv file.zip; touch pwned.txt #.zip lawnchair.zip
शेल mv file.zip निष्पादित करता है, फिर touch pwned.txt, और बाकी को टिप्पणी के रूप में अनदेखा कर देता है।
GITHUB_TOKEN या रिलीज़ साइनिंग कुंजियाँ)।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
सर्वर शुरू होने के बाद, इन URL पर जाएं:
| URL | विवरण |
|---|---|
http://localhost:3000/workflow/vulnerable | कमज़ोर वर्कफ़्लो — सबमिट करने पर कमांड इंजेक्शन निष्पादित होता है |
http://localhost:3001/workflow/patched | fcba413 पैच लागू के साथ समान वर्कफ़्लो |
कमज़ोर संस्करण रनर पर आपके इंजेक्ट किए गए कमांड को निष्पादित करेगा। पैच किया गया संस्करण इनपुट को शाब्दिक स्ट्रिंग के रूप में मानता है।
आप स्टैंडअलोन PoC भी चला सकते हैं:
cd poc
node exploit.js
यह पोर्ट 3000 पर एक न्यूनतम सर्वर शुरू करता है जो पूर्ण एप्लिकेशन संदर्भ के बिना समान बग प्रदर्शित करता है।
1. हमलावर artifactName इनपुट पैरामीटर को नियंत्रित करता है
2. GitHub Actions YAML में ${{ inputs.artifactName }} का विस्तार करता है
3. run स्टेप इसे bash को भेजता है
4. Bash अनकोटेड विशेष वर्ण देखता है और उन्हें कमांड सिंटैक्स के रूप में मानता है
5. कमांड रनर वातावरण विशेषाधिकारों के साथ निष्पादित होते हैं
┌────────────────────────────────────────────────────┐
│ 1. दुर्भावनापूर्ण इनपुट: │
│ │
│ artifactName = "file.zip; id #" │
│ │
│ 2. GitHub Actions YAML में प्रतिस्थापित करता है: │
│ │
│ run: mv file.zip; id #.zip lawnchair.zip │
│ │
│ 3. Bash देखता है: │
│ - mv file.zip │
│ - id <-- मनमाना कमांड │
│ - #.zip lawnchair.zip (अनदेखा) │
│ │
│ 4. शेल मनमाना कमांड निष्पादित करता है │
└────────────────────────────────────────────────────┘
संस्करण fcba413 इंटरपोलेटेड वेरिएबल के आसपास कोटेशन पेश करता है:
- name: Rename artifact
run: mv "${{ inputs.artifactName }}.zip" lawnchair.zip
कोटेशन शेल को विशेष वर्णों को पार्स करने से रोकते हैं। पेलोड शाब्दिक फ़ाइलनाम स्ट्रिंग के रूप में माना जाता रहता है।
सर्वोत्तम अभ्यास उपयोगकर्ता इनपुट को पूरी तरह से अलग करने के लिए पर्यावरण चर का उपयोग करना है:
- name: Rename artifact
env:
ARTIFACT_NAME: ${{ inputs.artifactName }}
run: mv "$ARTIFACT_NAME.zip" lawnchair.zip
पूर्ण कमिट देखें: fcba413
CVE-2026-39866/
├── README.md # यह फ़ाइल
├── docker-compose.yml # Docker लैब कॉन्फ़िगरेशन
├── app/
│ ├── Dockerfile # कंटेनर बिल्ड कॉन्फ़िगरेशन
│ ├── package.json # Node.js निर्भरताएँ
│ └── server.js # कमज़ोर + पैच किया गया वर्कफ़्लो रनर सिमुलेशन
└── poc/
└── exploit.js # स्टैंडअलोन न्यूनतम प्रूफ-ऑफ-कॉन्सेप्ट
रिपोर्ट किया गया: अभय कुमार। यह रिपॉज़िटरी केवल स्थानीय शैक्षिक उपयोग के लिए है। कमज़ोर सर्वर को सार्वजनिक नेटवर्क पर तैनात न करें।
केवल शैक्षिक उद्देश्य — पृथक वातावरण में उपयोग करें