octoscan: A static vulnerability scanner for GitHub action workflows

Octoscan

Octoscan is a static vulnerability scanner for GitHub action workflows.

Usage

download remote workflows

Octoscan can be run against a local git repository or you can download all the workflows with the dl action:

[pastacode lang=”markup” manual=”%24%20octoscan%20dl%20-h%20%20%0AOctoscan.%0A%0AUsage%3A%0A%09octoscan%20dl%20%5Boptions%5D%20–org%20%3Corg%3E%20%5B–repo%20%3Crepo%3E%20–token%20%3Cpat%3E%20–default-branch%20–max-branches%20%3Cnum%3E%20–path%20%3Cpath%3E%20–output-dir%20%3Cdir%3E%20–include-archives%5D%0A%0AOptions%3A%0A%09-h%2C%20–help%20%20%09%09%09%09%09%09Show%20help%0A%09-d%2C%20–debug%20%20%09%09%09%09%09%09Debug%20output%0A%09–verbose%20%20%09%09%09%09%09%09Verbose%20output%0A%09–org%20%3Corg%3E%20%20%09%09%09%09%09%09Organizations%20to%20target%0A%09–repo%20%3Crepo%3E%20%20%09%09%09%09%09%09Repository%20to%20target%0A%09–token%20%3Cpat%3E%20%20%09%09%09%09%09%09GHP%20to%20authenticate%20to%20GitHub%0A%09–default-branch%20%20%09%09%09%09%09Only%20download%20workflows%20from%20the%20default%20branch%0A%09–max-branches%20%3Cnum%3E%20%20%09%09%09%09%09Limit%20the%20number%20of%20branches%20to%20download%0A%09–path%20%3Cpath%3E%20%20%09%09%09%09%09%09GitHub%20file%20path%20to%20download%20%5Bdefault%3A%20.github%2Fworkflows%5D%0A%09–output-dir%20%3Cdir%3E%20%20%09%09%09%09%09Output%20dir%20where%20to%20download%20files%20%5Bdefault%3A%20octoscan-output%5D%0A%09–include-archives%20%20%09%09%09%09%09Also%20download%20archived%20repositories” message=”” highlight=”” provider=”manual”/]

[pastacode lang=”markup” manual=”.%2Foctoscan%20dl%20–token%20ghp_%3Ctoken%3E%20–org%20apache%20–repo%20incubator-answer” message=”” highlight=”” provider=”manual”/]

analyze

If you don’t know what to run just run this:

[pastacode lang=”markup” manual=”.%2Foctoscan%20scan%20path%2Fto%2Frepos%2F%20–disable-rules%20shellcheck%2Clocal-action%20–filter-triggers%20external” message=”” highlight=”” provider=”manual”/]

It will reduce false positives and give the most interesting results.

If you have downloaded the workflows with the dl command you might have duplicated workflows since by default octoscan will download all the workflows of all the branches. To delete duplicated workflows and speed up the analysis you can use the fdupes command before running the analysis:

[pastacode lang=”markup” manual=”fdupes%20-n%20-r%20-N%20-d%20path%2Fto%2Frepo” message=”” highlight=”” provider=”manual”/]

[pastacode lang=”markup” manual=”%24%20octoscan%20scan%20-h%0Aoctoscan%0A%0AUsage%3A%0A%09octoscan%20scan%20%5Boptions%5D%20–list-rules%0A%09octoscan%20scan%20%5Boptions%5D%20%3Ctarget%3E%0A%09octoscan%20scan%20%5Boptions%5D%20%3Ctarget%3E%20%5B–debug-rules%20–filter-triggers%3D%3Ctriggers%3E%20–filter-run%20–ignore%3D%3Cpattern%3E%20((–disable-rules%20%7C%20–enable-rules%20)%20%3Crules%3E)%20–config-file%20%3Cconfig%3E%5D%0A%0AOptions%3A%0A%09-h%2C%20–help%0A%09-v%2C%20–version%0A%09-d%2C%20–debug%0A%09–verbose%0A%09–json%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09JSON%20output%0A%09–oneline%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%09%09%09Use%20one%20line%20per%20one%20error.%20Useful%20for%20reading%20error%20messages%20from%20programs%0A%0AArgs%3A%0A%09%3Ctarget%3E%09%09%09%09%09Target%20File%20or%20directory%20to%20scan%0A%09–filter-triggers%20%3Ctriggers%3E%09%09%09Scan%20workflows%20with%20specific%20triggers%20(comma%20separated%20list%3A%20%22push%2Cpull_request_target%22%20or%20pre-configured%3A%20external%2Fallnopr)%0A%09–filter-run%09%09%09%09%09Search%20for%20expression%20injection%20only%20in%20run%20shell%20scripts.%0A%09–ignore%20%3Cpattern%3E%09%09%09%09Regular%20expression%20matching%20to%20error%20messages%20you%20want%20to%20ignore.%0A%09–disable-rules%20%3Crules%3E%09%09%09%09Disable%20specific%20rules.%20Split%20on%20%22%2C%22%0A%09–enable-rules%20%3Crules%3E%09%09%09%09Enable%20specific%20rules%2C%20this%20with%20disable%20all%20other%20rules.%20Split%20on%20%22%2C%22%0A%09–debug-rules%09%09%09%09%09Enable%20debug%20rules.%0A%09–config-file%20%3Cconfig%3E%09%09%09%09Config%20file.%0A%0AExamples%3A%0A%09%24%20octoscan%20scan%20ci.yml%20–disable-rules%20shellcheck%2Clocal-action%20–filter-triggers%20external” message=”” highlight=”” provider=”manual”/]

Rules

The complete list of rules can be found with this command:

[pastacode lang=”markup” manual=”%24%20octoscan%20scan%20–list-rules%20%20%0A2024%2F08%2F07%2016%3A50%3A48%20%5BINFO%5D%20Available%20rules%0A-%20dangerous-action%0A%09Check%20for%20dangerous%20actions.%0A-%20dangerous-checkout%0A%09Check%20for%20dangerous%20checkout.%0A-%20expression-injection%0A%09Check%20for%20expression%20injection.%0A-%20dangerous-write%0A%09Check%20for%20dangerous%20write%20operation%20on%20%24GITHUB_OUTPUT%20or%20%24GITHUB_ENV.%0A-%20local-action%0A%09Check%20for%20local%20actions.%0A-%20oidc-action%0A%09Check%20for%20OIDC%20actions.%0A-%20runner-label%0A%09Checks%20for%20GitHub-hosted%20and%20preset%20self-hosted%20runner%20labels%20in%20%22runs-on%3A%22%0A-%20unsecure-commands%0A%09Check%20’ACTIONS_ALLOW_UNSECURE_COMMANDS’%20env%20variable.%0A-%20known-vulnerability%0A%09Check%20for%20known%20vulnerabilities.%0A-%20bot-check%0A%09Check%20for%20if%20statements%20that%20are%20based%20on%20a%20bot%20identity.%0A-%20debug-external-trigger%0A%09Check%20for%20workflow%20that%20can%20be%20externally%20triggered.%0A-%20debug-artefacts%0A%09Check%20for%20workflow%20that%20upload%20artefacts.%0A-%20debug-js-exec%0A%09Check%20for%20workflow%20that%20execute%20system%20commands%20in%20JS%20scripts.%0A-%20repo-jacking%0A%09Verify%20that%20external%20actions%20are%20pointing%20to%20a%20valid%20GitHub%20user%20or%20organization.” message=”” highlight=”” provider=”manual”/]

dangerous-checkout

Triggers like workflow_run or pull_request_target run in a privileged context, as they have read access to secrets and potentially have write access on the targeted repository. Performing an explicit checkout on the untrusted code will result in the attacker code being downloaded in such context.

Install & Tutorial

Support Our Threat Intelligence

If you find our technology report and cybersecurity news helpful, consider supporting our work.

Crypto QR Code
USDT (TRC20):
TN8BdV8cp4T1Cd28gK9qTAnZknzzuwyUtm
USDT (ERC20):
0x3725e1a7d3bc5765499fa6aaafe307fabcd75bce