As a developer, you know that the first rule of secure code club is to use trusted third-party repositories. However, threat actors engaging in software supply chain attacks target the trusted sources precisely because they know that developers are likely to use them. For example, in a recent blog post, a security researcher explained how a PWN Request vulnerability could compromise credentials from a microsoft/confidential-sidecar-containers repository.
Protecting against PWN Request attacks, also called workflow event code injections, is particularly challenging, so understanding what they are and how attackers can exploit them is critical.
What is a PWN Request?
A PWN Request attack is also called a workflow event code injection because it exploits a vulnerability in events related to incoming pull requests (PR) that use the pull_request_target trigger. When this workflow trigger processes PRs from an external fork, malicious actors can use it to obtain repository write permissions or steal repository secrets. Since automatically processing PRs from an external fork can be risky, developers should use trusted sources.
However, even trusted repositories can be vulnerable if they meet all of the following conditions:
- Check out code from PR branch
- Run code from PR branch
- Lack deploy-environment or label-based gating
- Set write permissions for GITHUB_TOKEN
What does the pull_request_target workflow trigger do?
In a GitHub environment, the pull_request workflow trigger prevents write permissions and secret access as a default setting. However, this created limitations when the applications needed this access to process the PR. GitHub responded with the pull_request_target trigger.
With this trigger, a workflow can:
- Provide these permissions for PR from external forks
- Runs against the workflow and code from the base of the pull request
Assuming that it runs from a trusted resource, the workflow executes code and configuration already in the base repository, protecting it from any malicious modification to the Actions configuration file.
Pull_request_target is useful in cases where the workflow requires commenting on the PR but not checking out modified code. It creates a shortcut for passing around artifacts rather than requiring you to use the pull_request and workflow_run workflows.
If you want to use the pull_request_target workflow safely, you should ensure that it can’t influence the build or testing process, like by triggering a script that can operate on PR-controlled contents.
Some examples of use cases for pull_request_target workflows include ones that:
- Reformat and recommit code
- Diff the base and head repositories
- Grep the checked-out source for string or word matches
How do malicious actors compromise the workflow?
The problem arises when a repository runs the pull_request_target workflow then checks out and runs code from the PR branch. Typically, the workflow event code injection arises from a coding error.
The actions/checkout can introduce malicious code into the repository because it can accidentally execute arbitrary code from the incoming PR with access to repository secrets, enabling attackers to steal them.
Malicious actors can use malicious PRs in various ways, including:
- Submitting malicious changes to build scripts
- Redefining build scripts
- Writing payloads as new tests that will run with others
- Adding a malicious reference to an NPM package
Additionally, the pull_request_target workflow maintains the read/write repository token in its memory so any subsequent steps running the code can still read it from the disk.
How to remediate vulnerabilities
If you’re using the pull_request_target workflow, you need to do a little extra work to mitigate risks or remediate any existing vulnerabilities. At their core, these vulnerabilities arise from granting the workflow too much access to the repository, meaning that you need to review when and how you use it carefully.
If you’re the repository owner, you should:
- Use pull_request whenever possible
- Explicitly assign repository privileges using pull_request and workflow_run
Additionally, you should incorporate the following best practices for secure coding:
- Ensure that you use only trusted third-parties
- Review your code to ensure that you don’t combine pull_request_target and action/checkout
- Close or rebase any PRs opened before fixing the vulnerable workflow
Qwiet AI: Automated Code Analysis for GitHub Actions
PreZero integrates directly into your GitHub PR workflow, enabling automated code analysis when you use GitHub Actions. You can choose to consistently scan the main branch for continuously updated code analysis results, then compare these with previous scans.
Additionally, you can post your preZero results as a comment to your GitHub pull request, eliminating accidental secret exposure while still documenting findings. Our platform identifies the critical issues and then gives you a link to the scan, reducing the risks of sharing code snippets.
Take our preZero platform for a free spin to see how Qwiet AI can help you identify shadow code.