CodeQL सप्लाई चेन अटैक का खतरा – सार्वजनिक GitHub secret key से शुरू हुई सुरक्षा घटना
(praetorian.com)- अगर सार्वजनिक GITHUB_TOKEN की बहुत कम वैधता वाली अवधि का फायदा उठाया जाता, तो CodeQL इस्तेमाल करने वाले कई repositories के GitHub Actions workflows में code execution तक पहुंचने वाला एक सप्लाई चेन अटैक रास्ता खुल सकता था
- यह token
github/codeql-actionrepository की एक failed debug workflow द्वारा अपलोड किए गए workflow artifact में था, औरcontents: write,actions: write,packages: writepermissions वाला GitHub App installation token था - अटैक की सफलता इस race condition पर निर्भर थी कि artifact upload होने के बाद job खत्म होने से पहले token डाउनलोड करके इस्तेमाल किया जा सके; वास्तविक logs के आधार पर लगभग 1.022 सेकंड, और अवलोकन के अनुसार लगभग 2 सेकंड के भीतर branch बनाना,
poc.txtpush करना और tag बनाना सफल हुआ - क्योंकि default CodeQL configuration अंदरूनी तौर पर
github/codeql-actionके v3 tag को चलाती थी, और वह tag immutable नहीं था, इसलिए अगर attacker उस tag को malicious commit पर ले जाता तो default CodeQL workflow इस्तेमाल करने वाली repositories भी प्रभावित हो सकती थीं - GitHub ने report मिलने के लगभग 3 घंटे बाद debug artifact upload को disable करने वाला PR जारी किया, CVE-2025-24362 असाइन किया, और advisory में कहा कि platform या system compromise के कोई सबूत नहीं मिले
सार्वजनिक artifact से शुरू हुआ CodeQL सप्लाई चेन अटैक रास्ता
- एक सार्वजनिक secret, GitHub CodeQL के खिलाफ संभावित supply chain attack में बदल सकता था
- यह secret एक बार में सिर्फ लगभग 1.022 सेकंड के लिए valid था, लेकिन उसी दौरान attacker GitHub Actions workflow के भीतर code execution तक पहुंचने वाले कदम पूरे कर सकता था
- इसका प्रभाव GitHub Cloud और GitHub Enterprise दोनों तक पहुंच सकता था
- संभावित नुकसान इस प्रकार थे
- CodeQL इस्तेमाल करने वाली private repositories के source code का leakage
- CodeQL workflow job के भीतर मौजूद GitHub Actions secrets की चोरी
- उस internal infrastructure में code execution जहां CodeQL workflow चलती है
- CodeQL इस्तेमाल करने वाली repositories में GitHub Actions Cache उपयोग करने वाले workflows के secrets की चोरी
- GitHub advisory के अनुसार GitHub को platform या system compromise का कोई सबूत नहीं मिला
secret कैसे मिला
- GitHub Actions workflow artifact डाउनलोड करके, archive को recursive तरीके से extract करने के बाद, Nosey Parker से secrets scan करने वाला Actions Artifacts Secret Scanner इस्तेमाल किया गया
- यह feature Chariot में integrate किया गया और Gato feature के रूप में open source किया गया
- एक दिन तक scan करने के बाद
github/codeql-actionrepository के artifact में token मिला- target artifact “PR Check – Debug artifacts after failure” workflow द्वारा अपलोड किया गया
my-debug-artifactszip था - उसके भीतर
my-db-java-partial.zipextract करने पर crash report मेंghs_से शुरू होने वाला GitHub Token मिला - manual जांच में पता चला कि यह GitHub Runner के environment variables वाली file में stored GitHub App installation token था
- target artifact “PR Check – Debug artifacts after failure” workflow द्वारा अपलोड किया गया
GitHub Actions, artifact और CodeQL का संबंध
- GitHub Actions, YAML workflow में परिभाषित jobs को runner पर चलाने वाला CI/CD platform है
- हर workflow run एक auto-generated GitHub App installation token यानी GITHUB_TOKEN बनाता है
- runner इसी token से GitHub पर authenticate होकर workflow के जरूरी काम करता है
- permissions workflow file, repository और organization level पर configure की जा सकती हैं
- GitHub Actions workflow artifact वे files हैं जिन्हें workflow बाद में इस्तेमाल के लिए GitHub Actions में store करती है
- default रूप से repository read permission वाले लोग इन्हें access कर सकते हैं
- ये अधिकतम 90 दिनों तक stored रहती हैं
- CodeQL GitHub का code analysis engine है, जिसका उपयोग GitHub repositories में static analysis करके vulnerabilities खोजने के लिए होता है
- CodeQL जैसे security tools को अक्सर sensitive systems और data तक access चाहिए होता है, इसलिए compromise होने पर वे backdoor बन सकते हैं
token permissions और race condition
- workflow logs के “Setup Job” चरण में यह GITHUB_TOKEN full write permissions वाला पाया गया
- खास तौर पर महत्वपूर्ण permissions ये थीं
contents: write: branch बनाना, tag बनाना, release artifact upload करनाactions: write: Actions jobs औरworkflow_dispatchevent trigger करनाpackages: write: package upload करना
- क्योंकि token सिर्फ उस workflow job के चलने तक valid था, अटैक के लिए तीन शर्तें जरूरी थीं
- token में write permission होनी चाहिए
- job खत्म होने से पहले artifact लाने के लिए upload artifact API v4 इस्तेमाल होना चाहिए
- artifact upload और job completion के बीच इतना समय होना चाहिए कि token download, extract और use किया जा सके
- CodeQL ने
actions/upload-artifactaction सीधे इस्तेमाल नहीं किया, बल्कि source code में upload artifact client को manually use किया; code comments के अनुसार version 4 इस्तेमाल हो रहा था - raw GitHub logs के हिसाब से समयांतराल बेहद कम था
- “Finalizing artifact upload”: 17:22:09.888
- “Cleaning up orphan processes”: 17:22:10.911
- गणना के अनुसार यह लगभग 1.022 सेकंड था, और अवलोकन में cleanup के बाद करीब 1 सेकंड और token valid रहा, इसलिए कुल लगभग 2 सेकंड माना गया
PoC: artifact_racer.py चलाना
- सत्यापन के लिए Python script
artifact_racer.pyलिखी गई - इसका flow इस प्रकार था
github/codeql-actionrepository में “PR Check – Debug artifacts after failure” workflow शुरू होती है या नहीं, इसे लगातार query करना- चल रही workflow के artifacts को monitor करना
- artifact दिखते ही उसे download करके GITHUB_TOKEN निकालना
- निकाले गए token से नई branch बनाना
- उस branch पर
poc.txtनाम की खाली file push करना - उस commit पर नया tag बनाना
- artifact का size लगभग 21MB था, इसलिए समय सीमा के भीतर सफलता संभव मानी गई
- test repository में सफल होने के बाद इसे
github/codeql-actionrepository पर चलाया गया - लगभग 2 घंटे बाद workflow चली और script ने token लेकर branch creation, file push और tag creation सफलतापूर्वक कर लिया
tag manipulation से बढ़ा प्रभाव
- attacker इस token से unprotected branch में malicious code जोड़ सकता था
- अधिक stealthy तरीके से merge से पहले feature branch में छोटा malicious बदलाव डालकर merge का इंतजार करने की रणनीति भी संभव थी
- tag creation permission भी महत्वपूर्ण थी
- अगर malicious code वाले commit पर
v3tag लगा दिया जाता, तोcodeql-action@v3manually इस्तेमाल करने वाले users malicious code चला सकते थे
- अगर malicious code वाले commit पर
- इससे भी बड़ा प्रभाव default CodeQL configuration से आया
- repository settings में CodeQL को default configuration के रूप में enable करने पर, repository workflow list में दिखाई न देने वाली एक special GitHub Actions workflow चलती है
- यह workflow repository checkout, CodeQL initialization, CodeQL scan और result upload करती है
- अंदरूनी तौर पर यह
github/codeql-actionrepository की action को उस commit से चलाती है जिस पर v3 tag point कर रहा होता है
- उस समय
v3tag immutable नहीं था, और GitHub द्वारा सुझाया गया workflow pinning भी इस्तेमाल नहीं हो रहा था - अगर attacker compromised GITHUB_TOKEN से
v3tag को malicious commit पर ले जाता, तो default CodeQL workflow इस्तेमाल करने वाली repositories malicious CodeQL action चलातीं - क्योंकि CodeQL action target repository का source code checkout करती है, malicious action default CodeQL configuration इस्तेमाल करने वाली repositories का source code exfiltrate कर सकती थी
GitHub Actions Cache poisoning का रास्ता
- default CodeQL action का GITHUB_TOKEN केवल read permission वाला होता है, इसलिए सिर्फ default configuration के आधार पर repository write operations, release backdoor, या
workflow_dispatchसे secrets theft सीधे संभव नहीं था - लेकिन default CodeQL action repository की main branch पर चलती है
- GitHub repository की main branch पूरे repository में इस्तेमाल होने वाली cache entries लिख सकती है, जिससे GitHub Actions cache poisoning का अवसर बनता है
- GitHub Actions Cache Poisoning, Adnan Khan की पोस्ट में वर्णित तकनीक है, और Cacheract cache poisoning के जरिए build pipeline में persistence छोड़ने वाला malware है
- अगर attacker CodeQL workflow में Cacheract deploy करता, तो यह flow संभव था
- cache entry का अनुमान लगाना
- उस entry को malicious action से overwrite करना
actions/cacheइस्तेमाल करने वाले workflow में code execution हासिल करना- उस workflow के GitHub Actions secrets और high-privilege GITHUB_TOKEN चुराना
- malicious CodeQL action पकड़े जाने और vulnerability fix हो जाने के बाद भी, Cacheract cache poisoning जारी रख सकता था
- CodeQL और
actions/cacheदोनों इस्तेमाल करने वाले प्रमुख repos के उदाहरण के रूप में Homebrew, Angular, Grafana की पुष्टि की गई
CVE-2025-24362 और fix
- इस disclosure के परिणामस्वरूप CVE-2025-24362 असाइन किया गया
- सार्वजनिक GITHUB_TOKEN, failed code scanning workflow के बाद CodeQL Action द्वारा upload किए गए debug artifact के भीतर था
- CodeQL Actions repository जानबूझकर failure trigger कर रही थी, लेकिन अगर दूसरे CodeQL Actions users में भी ऐसा failure हुआ होता, तो उनके अपने secrets workflow environment variables के जरिए expose हो सकते थे
- यह issue CodeQL Action 3.28.3 में fix किया गया
- सबसे बड़ा संभावित प्रभाव CVE से अधिक, CodeQL Actions repository के खिलाफ exploit करके CodeQL users पर supply chain attack चलाने वाले रास्ते में था
GitHub की प्रतिक्रिया और सुझाए गए mitigation उपाय
- GitHub की response timeline इस प्रकार थी
- 22 जनवरी 2025 15:13 UTC: GitHub को report submit की गई
- 22 जनवरी 2025 17:48 UTC: GitHub ने receipt acknowledge की
- 22 जनवरी 2025 18:28 UTC: GitHub ने vulnerability confirm की, “PR Check – Debug artifacts after failure” workflow को अस्थायी रूप से disable किया, और debug artifact upload disable करने वाला PR submit किया
- 24 जनवरी 2025: GitHub ने CVE-2025-24362 असाइन किया और security advisory प्रकाशित की
- GitHub Actions workflow artifacts में secret exposure का जोखिम घटाने के लिए ये कदम सुझाए गए
- workflow artifact में सिर्फ चुनी हुई files या directories ही upload करें
- environment variables,
.git/config, और runner की<path_to_runner_dir>/_work/_temp/directory की files को artifact में upload करने से बचें - GITHUB_TOKEN permissions को read-only तक सीमित रखें
- artifact upload से पहले secret scan करें
1 टिप्पणियां
Hacker News की टिप्पणियां
अगर GitHub ने immutable actions को जल्दी आगे बढ़ाया होता, तो इसका असर बहुत कम होता
मैं बार-बार कहता रहता हूं कि यह फीचर अभी GitHub Actions के attack surface के 70% से ज्यादा हिस्से को रोक देगा। हर हफ्ते कोई न कोई incident होते देख कर लगता है कि अब इसे रिलीज करने का समय आ गया है
[1] https://github.com/features/preview/immutable-actions
यह समझाया नहीं गया कि इस temporary token के पास नए deployments बनाने और artifact attestations जनरेट करने की permissions क्यों थीं
उन्होंने कहा कि fix के तौर पर debug logs बंद कर दिए गए, लेकिन यह जवाब नहीं दिया कि code analysis engine के हिसाब से temporary token permissions को ज्यादा सही तरीके से बदला गया या नहीं
पहले default केवल permissive setting हुआ करता था, इसलिए पुराने organizations और repositories में दुर्भाग्य से अक्सर यही setting इस्तेमाल होती है
नई repository बनाने पर वह parent organization का default inherit करती है, इसलिए अगर कोई इसे न बदले तो यह unsafe default बना रहता है। user-wide setting नहीं है, इसलिए व्यक्तिगत ownership वाली नई repositories restrictive default इस्तेमाल करती हैं। मेरी जानकारी में नए बनाए गए organizations भी बेहतर default इस्तेमाल करते हैं
[0]: https://docs.github.com/en/actions/security-for-github-actio...
मुझे यह भरोसा बढ़ता जा रहा है कि CI और CD पूरी तरह अलग environments होने चाहिए। CI compromise हो जाए तो भी CD-related tokens leak नहीं होने चाहिए
उदाहरण के लिए
"sub":"repo:octo-org/octo-repo:environment:prod"[1] जैसी condition अनिवार्य रूप से satisfy करनी हो, और अगर system को और मजबूत बनाना हो तो दूसरे [fun claims][] भी add किए जा सकते हैं1: https://docs.github.com/en/actions/security-for-github-actio...
fun claims: https://github.com/github/actions-oidc-debugger#readme
response time मजाक नहीं था। GitHub की response काफी impressive थी
Prater surname वाले व्यक्ति के तौर पर, क्योंकि यह नाम Praetorian से निकला है, काश मेरे पास praetorian.com होता
public GitHub Actions इस्तेमाल करना खुद मुसीबत बुलाना है, खासकर अगर आप workflow procedures analyze नहीं कर रहे हैं
इसके बजाय woodpecker या दूसरे अच्छे CI builders (circle, travis, gitlab आदि) को खुद host करना बेहतर है
हमने OpenZFS PRs पर CodeQL apply किया हुआ था। यह OpenZFS के लिए समस्या नहीं है, क्योंकि हमारा code secret नहीं है :)
फिर भी कम से कम यह अच्छी बात है कि issue जल्दी resolve हो गया
क्या यह fix हो गया?
इस site की performance इतनी खराब है कि scroll करना भी मुश्किल है