
Octoscan is a static vulnerability scanner for GitHub action workflows.
Octoscan GitHub एक्शन वर्कफ़्लो के लिए एक स्थैतिक भेद्यता स्कैनर है।
$ go mod tidy
$ go build
या Docker के साथ:
$ docker pull ghcr.io/synacktiv/octoscan:latest
Octoscan को स्थानीय git रिपॉजिटरी के विरुद्ध चलाया जा सकता है या आप dl एक्शन के साथ सभी वर्कफ़्लो डाउनलोड कर सकते हैं:
$ octoscan dl -h
Octoscan.
Usage:
octoscan dl [options] --org <org> [--repo <repo> --token <pat> --default-branch --max-branches <num> --path <path> --output-dir <dir> --include-archives]
Options:
-h, --help Show help
-d, --debug Debug output
--verbose Verbose output
--org <org> Organizations to target
--repo <repo> Repository to target
--token <pat> GHP to authenticate to GitHub
--default-branch Only download workflows from the default branch
--max-branches <num> Limit the number of branches to download
--path <path> GitHub file path to download [default: .github/workflows]
--output-dir <dir> Output dir where to download files [default: octoscan-output]
--include-archives Also download archived repositories
./octoscan dl --token ghp_<token> --org apache --repo incubator-answer
यदि आप नहीं जानते कि क्या चलाना है, तो बस यह चलाएँ:
./octoscan scan path/to/repos/ --disable-rules shellcheck,local-action --filter-triggers external
यह false positives को कम करेगा और सबसे दिलचस्प परिणाम देगा।
यदि आपने dl कमांड के साथ वर्कफ़्लो डाउनलोड किए हैं, तो आपके पास डुप्लिकेट वर्कफ़्लो हो सकते हैं, क्योंकि डिफ़ॉल्ट रूप से octoscan सभी ब्रांचों के सभी वर्कफ़्लो डाउनलोड करता है। डुप्लिकेट वर्कफ़्लो को हटाने और विश्लेषण को तेज़ करने के लिए आप विश्लेषण चलाने से पहले fdupes कमांड का उपयोग कर सकते हैं:
fdupes -n -r -N -d path/to/repo
$ octoscan scan -h
octoscan
Usage:
octoscan scan [options] --list-rules
octoscan scan [options] <target>
octoscan scan [options] <target> [--debug-rules --filter-triggers=<triggers> --filter-run --ignore=<pattern> ((--disable-rules | --enable-rules ) <rules>) --config-file <config>]
Options:
-h, --help
-v, --version
-d, --debug
--verbose
--format <format> Output format, json, sarif or custom template to format error messages in Go template syntax. See https://github.com/rhysd/actionlint/tree/main/docs/usage.md#format
--oneline Use one line per one error. Useful for reading error messages from programs
Args:
<target> Target File or directory to scan
--filter-triggers <triggers> Scan workflows with specific triggers (comma separated list: "push,pull_request_target" or pre-configured: external/allnopr)
--filter-run Search for expression injection only in run shell scripts.
--ignore <pattern> Regular expression matching to error messages you want to ignore.
--disable-rules <rules> Disable specific rules. Split on ","
--enable-rules <rules> Enable specific rules, this will disable all other rules. Split on ","
--debug-rules Enable debug rules.
--config-file <config> Config file.
Examples:
$ octoscan scan ci.yml --disable-rules shellcheck,local-action --filter-triggers external
इस टूल का उपयोग सीधे GitHub एक्शन के रूप में भी किया जा सकता है, ताकि push/pull_request ईवेंट पर आपकी रिपॉजिटरी स्कैन हो सके। अधिक जानकारी के लिए कृपया इस रिपॉजिटरी को देखें।
नियमों की पूरी सूची इस कमांड से देखी जा सकती है:
$ octoscan scan --list-rules
2024/08/07 16:50:48 [INFO] Available rules
- shellcheck
Checks for shell script sources in "run:" using shellcheck
- credentials
Checks for credentials in "services:" configuration
- dangerous-action
Check for dangerous actions.
- dangerous-checkout
Check for dangerous checkout.
- expression-injection
Check for expression injection.
- dangerous-write
Check for dangerous write operation on $GITHUB_OUTPUT or $GITHUB_ENV.
- local-action
Check for local actions.
- runner-label
Checks for GitHub-hosted and preset self-hosted runner labels in "runs-on:"
- unsecure-commands
Check 'ACTIONS_ALLOW_UNSECURE_COMMANDS' env variable.
- known-vulnerability
Check for known vulnerabilities.
- bot-check
Check for if statements that are based on a bot identity.
- dangerous-artefact
Check for workflow that upload artefacts containing sensitive files.
- debug-external-trigger
Check for workflow that can be externally triggered.
- debug-artefacts
Check for workflow that upload artefacts.
- debug-js-exec
Check for workflow that execute system commands in JS scripts.
- debug-oidc-action
Check for OIDC actions.
- repo-jacking
Verify that external actions are pointing to a valid GitHub user or organization.
workflow_run या pull_request_target जैसे ट्रिगर विशेषाधिकार प्राप्त संदर्भ में चलते हैं, क्योंकि उनके पास secrets तक पढ़ने की पहुँच होती है और संभावित रूप से लक्षित रिपॉजिटरी पर लिखने की पहुँच होती है। अविश्वसनीय कोड पर स्पष्ट checkout करने से उस संदर्भ में हमलावर का कोड डाउनलोड हो जाएगा।

यह नियम उपयोगकर्ता को चेतावनी देता है यदि कोई खतरनाक एक्शन उपयोग किया जाता है। यह मुख्य रूप से अविश्वसनीय artifacts पर केंद्रित है।
विभिन्न वर्कफ़्लो के बीच डेटा पास करने के लिए artifacts का उपयोग करना आम प्रथा है। हम अक्सर इसका सामना workflow_run ट्रिगर के साथ करते हैं, जहाँ ट्रिगर करने वाला वर्कफ़्लो कुछ डेटा तैयार करता है जिसे बाद में ट्रिगर किए गए वर्कफ़्लो को भेजा जाता है। इस artifact डेटा की अविश्वसनीय प्रकृति को देखते हुए, इसे सावधानी से संभालना और इसे संभावित खतरे के रूप में पहचानना महत्वपूर्ण है। यह भेद्यता इस तथ्य से उत्पन्न होती है कि बाहरी संस्थाएँ, जैसे दुर्भावनापूर्ण हमलावर, artifact डेटा की सामग्री को प्रभावित कर सकती हैं।

GitHub डिफ़ॉल्ट environment variables बनाता है जिनका उपयोग वर्कफ़्लो के हर चरण में किया जा सकता है। GITHUB_ENV और GITHUB_OUTPUT वेरिएबल विशेष रूप से दिलचस्प हैं। एक चरण में environment variable परिभाषित करना और उस वेरिएबल का उपयोग दूसरे चरण में करना संभव है। यह संबंधित वेरिएबल में लिखकर किया जा सकता है। यदि कोई उपयोगकर्ता सेट किए जा रहे वेरिएबल की सामग्री को नियंत्रित कर सकता है, तो यह मनमाना कोड निष्पादन (arbitrary code execution) का कारण बन सकता है।

प्रत्येक वर्कफ़्लो ट्रिगर एक संबद्ध GitHub संदर्भ के साथ आता है, जो इसे आरंभ करने वाले ईवेंट के बारे में व्यापक जानकारी प्रदान करता है। इसमें ईवेंट को ट्रिगर करने वाले उपयोगकर्ता, ब्रांच का नाम और अन्य प्रासंगिक संदर्भ जानकारी का विवरण शामिल होता है। इस ईवेंट डेटा के कुछ घटक, जैसे आधार रिपॉजिटरी का नाम या pull request संख्या, को ईवेंट आरंभ करने वाले उपयोगकर्ता द्वारा हेरफेर या इंजेक्शन के लिए शोषित नहीं किया जा सकता है (उदाहरण के लिए, pull request के मामले में)। यह वर्कफ़्लो निष्पादन के दौरान GitHub संदर्भ द्वारा प्रदान की गई जानकारी पर नियंत्रण और सुरक्षा का एक स्तर सुनिश्चित करता है।
हालाँकि, कुछ तत्वों को हमलावर द्वारा नियंत्रित किया जा सकता है और उपयोग से पहले उन्हें सैनिटाइज़ किया जाना चाहिए। ऐसे तत्वों की सूची निम्नलिखित है:
github.event.issue.titlegithub.event.issue.bodygithub.event.pull_request.titlegithub.event.pull_request.bodygithub.event.comment.bodygithub.event.review.bodygithub.event.pages.*.page_namegithub.event.commits.*.messagegithub.event.head_commit.messagegithub.event.head_commit.author.emailgithub.event.head_commit.author.namegithub.event.commits.*.author.email
GitHub आपके अपने runners होस्ट करने और वर्कफ़्लो में जॉब चलाने के लिए उपयोग किए जाने वाले वातावरण को अनुकूलित करने की सुविधा प्रदान करता है। ऐसे runners को self-hosted कहा जाता है।
Self-hosted runners दो प्रकार के होते हैं: ephemeral और non-ephemeral। डिफ़ॉल्ट रूप से, runners non-ephemeral होते हैं, जिसका अर्थ है कि जॉब पूरी होने के बाद runner द्वारा उपयोग किया गया वातावरण साफ नहीं किया जाता है। यदि हमलावर non-ephemeral runner पर कोड निष्पादित करने में सफल हो जाते हैं, तो वे पृष्ठभूमि में एक प्रोसेस जोड़कर उसमें backdoor लगा सकते हैं और संवेदनशील secrets चुरा सकते हैं। इसलिए इस प्रकार के runners अत्यंत संवेदनशील होते हैं।
Non-ephemeral runners को रन लॉग देखकर पहचाना जा सकता है। इस प्रक्रिया को स्वचालित करने के लिए gato नामक टूल का उपयोग किया जा सकता है।

Repo jacking भेद्यता DEFCON 31 में Asi Greenholts द्वारा प्रस्तुत की गई थी। यह भेद्यता तब उत्पन्न होती है जब कोई GitHub एक्शन किसी गैर-मौजूद GitHub संगठन या उपयोगकर्ता पर एक एक्शन का संदर्भ देता है।

ध्यान दें कि यह नियम यह जाँचने के लिए इंटरनेट की आवश्यकता है कि हमला संभव है या नहीं। अन्य सभी जाँचें ऑफ़लाइन की जाती हैं।
Actions में runner मशीन के साथ इंटरैक्ट करने की क्षमता होती है, जिससे वे environment variables सेट कर सकते हैं, अन्य actions द्वारा उपयोग के लिए आउटपुट मान परिभाषित कर सकते हैं, आउटपुट लॉग में डीबग संदेश शामिल कर सकते हैं, और कई अन्य कार्य कर सकते हैं। हालाँकि, 2020 से पहले, STDOUT में डेटा लिखकर environment variables को नियंत्रित करना संभव था, जैसे:
run: |
echo "##[set-env name=ENV_NAME;]value"
# or
echo "echo "::set-env name=ENV_NAME::value"
लागू किए गए वर्कफ़्लो कमांड स्वाभाविक रूप से असुरक्षित थे, क्योंकि STDOUT पर लॉग करना आम प्रथा थी। इस भेद्यता ने संभावित हमलों के रास्ते खोल दिए, जिससे दुर्भावनापूर्ण payloads को आसानी से इंजेक्ट किया जा सकता था और set-env कमांड को ट्रिगर किया जा सकता था। Environment variables को संशोधित करने की क्षमता ने रिमोट कोड निष्पादन के कई रास्ते पेश किए, जिनमें से एक विशेष रूप से स्पष्ट payload वह था जिसे पहले प्रदर्शित किया गया था। इस भेद्यता को सबसे पहले Project Zero के एक सुरक्षा शोधकर्ता द्वारा रिपोर्ट किया गया था।
हालाँकि set-env कमांड अप्रचलित (deprecated) है और डिफ़ॉल्ट रूप से उपयोग योग्य नहीं है, यदि कोई डेवलपर वर्कफ़्लो में ACTIONS_ALLOW_UNSECURE_COMMANDS environment variable सेट करता है, तो set-env कमांड उपलब्ध हो जाता है और इसका उपयोग किया जा सकता है:

निम्नलिखित जाँच को बायपास करना संभव है:
jobs:
merge-dependabot-pr:
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]'
steps:
...
हमले का विचार यह है कि एक फोर्क की गई रिपॉजिटरी पर Dependabot को इस तरह ट्रिगर किया जाए कि फोर्क की गई रिपॉजिटरी पर एक PR Dependabot द्वारा बनाया जाए, फिर Dependabot ब्रांच से एक PR कमजोर रिपॉजिटरी पर खोला जाए, और अंत में कमजोर वर्कफ़्लो को लॉन्च करने के लिए Dependabot को फिर से ट्रिगर किया जाए।

सभी शोषण विवरण आप यहाँ पा सकते हैं: https://www.synacktiv.com/publications/github-actions-exploitation-dependabot
osv.dev के आधार पर ज्ञात कमजोर actions खोजें।
उन वर्कफ़्लो की जाँच करें जो .git/config जैसी संवेदनशील फ़ाइलों वाले artefacts अपलोड करते हैं। यह नियम इस लेख पर आधारित है।
services: कॉन्फ़िगरेशन में credentials की जाँच करता है। यह नियम actionlint से आया है।

सभी bash कार्यों पर shellcheck चलाएँ। यह नियम actionlint से आया है।
यदि कोई स्थानीय GitHub एक्शन उपयोग किया जाता है तो अलर्ट उठाएँ। फिलहाल टूल स्थानीय एक्शन फ़ाइलों को पार्स नहीं कर सकता है, इसलिए अलर्ट उठाया जाता है, क्योंकि उनमें भी भेद्यताएँ हो सकती हैं।
OIDC actions का पता लगाएँ। OIDC actions का उपयोग करने वाले वर्कफ़्लो कुछ क्लाउड प्रदाताओं तक पहुँचने के लिए एक अच्छा लक्ष्य हो सकते हैं। इस नियम से कोई भेद्यता संबद्ध नहीं है, लेकिन यदि कोई ऐसी भेद्यता है जो इस टूल द्वारा नहीं मिली है, तो इस एक्शन पर करीब से नज़र डालना दिलचस्प हो सकता है।
💡 यह अब एक डीबग नियम है, इसे खोजने के लिए आपको --debug-rules जोड़ने की आवश्यकता है।
यह टूल actionlint के बिना विकसित नहीं किया जा सकता था। @rhysd को बहुत धन्यवाद।
github.event.commits.*.author.namegithub.event.pull_request.head.refgithub.event.pull_request.head.labelgithub.event.pull_request.head.repo.default_branchgithub.head_refenv.*steps.*.outputs.*needs.*.outputs.*