Full Report
GitHub Actions permissions are really complicated to think about when secrets come into the mix. If someone makes a PR, do they have access to the secrets? There are different modes of these but it really makes a difference what code is ran on the repository. In the case of a Java formatter in the typically "safe" pull_request_target, it was checking out the user's PR from the Pull Request. By placing in a malicious pom.xml file, RCE could be gained in the context of the PR. Since the action can have secrets, this is a serious security issue. Using the secrets and ACCESS_TOKEN, it may have been possible to edit the repository itself. This attack is known as a "Pwn Request". To protect against it, developers should be very wary about externally facing actions on GitHub. Additionally, scope tokens down as much as possible. Good write up!
Analysis Summary
# Vulnerability: Remote Code Execution via Malicious `pom.xml` in Attacker-Controlled Pull Request Checkout within `pull_request_target`
## CVE Details
- CVE ID: Not explicitly provided in the text (This appears to be a zero-day disclosed via a VRP, details might be proprietary or tracked internally without an immediate public CVE).
- CVSS Score: Not explicitly provided.
- CWE: CWE-20 (Improper Input Validation) is applicable, as accepting attacker-controlled content (`pom.xml`) leads to execution error.
## Affected Systems
- Products: GitHub Actions workflows utilizing the "Java formatter action" logic.
- Versions: Unspecified, but affects configurations where the action runs on the `pull_request_target` event and checks out the PR reference.
- Configurations: Any repository configured to run the vulnerable formatter action (which runs `mvn com.coveo:fmt-maven-plugin:format`) upon receiving a `pull_request_target` event.
## Vulnerability Description
The vulnerability lies in the insecure combination of using the **`pull_request_target`** event handler with operations that process files supplied by the Pull Request author.
1. **`pull_request_target` Context:** This event runs jobs with the full context and secrets of the **base repository**, granting elevated permissions, including the standard `GITHUB_TOKEN` with write access to the repository.
2. **Attacker Control:** The vulnerable formatter action checks out the code from the attacker-controlled branch/PR reference.
3. **RCE Trigger:** The action proceeds to execute `mvn com.coveo:fmt-maven-plugin:format`. By injecting a malicious `pom.xml` file into the checked-out code, an attacker can configure a custom `pluginRepository` pointing to an attacker-controlled location.
4. **Exploitation:** The Maven process downloads and executes a backdoored version of the formatting plugin, leading to Remote Code Execution (RCE) within the permissions context of the **base repository runner**.
## Exploitation
- Status: Proof-of-Concept (PoC) available (demonstrated by the researcher in a controlled environment).
- Complexity: Low to Medium (Requires creating a controlled Maven repository and modifying the `pom.xml`).
- Attack Vector: Adjacent (Requires creating a Pull Request against the target repository).
## Impact
- Confidentiality: **High** (Exposure of repository secrets like `GITHUB_TOKEN` and custom repository secrets).
- Integrity: **Critical** (The attacker gains RCE in the base repository context, allowing them to commit malicious code back to the repository, as demonstrated with the `tigres-builder` commit).
- Availability: Moderate (Potential for workflow disruption, though the primary impact is data/integrity loss).
## Remediation
### Patches
- The underlying issue (improper handling of untrusted code execution context in `pull_request_target`) was reported on 2020-12-17 and fixed internally by January 8, 2021.
- **The fix involves changing the default behavior of GitHub Actions runners to prevent running arbitrary code (like Maven) against untrusted branches when using `pull_request_target`, or ensuring the checkout uses the base repository's code if necessary for trusted actions, or running the job in the less-privileged `pull_request` context instead.**
### Workarounds
1. **Change Event Trigger:** If possible, change workflows that process external PR code from `pull_request_target` (which has full secret access) to `pull_request` (which has limited permissions by default).
2. **Permission Scoping:** If `pull_request_target` must be used, ensure that the action does not execute untrusted external binaries or commands based on files originating from the PR (e.g., by disabling Maven dependency resolution pointing outside trusted sources).
3. **Token Scoping:** Limit the permissions of the `GITHUB_TOKEN` to the absolute minimum required for the job to function. (Though in this case, the RCE itself allowed the use of the existing token scope).
## Detection
- Indicators of Compromise:
- Unexpected commits originating from the GitHub Actions runner account, especially if they modify repository files in ways unrelated to the formatter job's purpose (e.g., pushing backdoors).
- Actions logs showing unexpected execution details related to Maven or external plugin repositories during the formatting step.
- Detection Methods and Tools:
- Comprehensive auditing of execution paths within `pull_request_target` jobs to verify that only trusted input is processed by execution engines (like Maven).
- Monitoring for unusual network egress from GitHub Actions runners that connect to external artifact repositories during trusted jobs.
## References
- Security Advisory Discussion (VRP Timeline): Context suggests this was fixed internally following a VRP report.
- Relevant concept: This behavior often relates to the "Pwn Request" or "malicious PR checkout" class of GitHub Actions vulnerabilities.