Skip to content

🚨 [SECURITY] Security Red Team Findings - 2026-02-22 (Weekly Full Scan) #17735

@github-actions

Description

@github-actions

Weekly security red team scan completed on 2026-02-22 (Sunday full scan). 1 confirmed finding requiring action: an incomplete security fix in upload_assets.cjs. 2 low-risk mitigated patterns and 1 test-only accepted-risk pattern also documented.

Scan Summary

Metric Value
Scan Mode WEEKLY FULL (Sunday)
Technique full-comprehensive (all 6 techniques)
Files Analyzed 250 (216 .cjs + 34 .sh)
Confirmed Findings 1 (Medium)
Mitigated/Low Risk 2
Accepted Risk 1 (test-only)
Malicious Patterns 0
Secret Exfiltration 0
Backdoors 0

Finding 1 — INCOMPLETE SECURITY FIX (Medium)

Location: actions/setup/js/upload_assets.cjs:156

Description: The security fix commit d07e64c3 ("fix: supply chain and shell injection security findings", Feb 20 2026) converted all template-string exec.exec() calls in upload_assets.cjs to the safe array form — except line 156, which still uses a template string with an unsanitized value:

// Line 156 — NOT fixed by d07e64c3
await exec.exec(`git add "\$\{targetFileName}"`);

All other exec.exec calls in the same file were correctly updated:

await exec.exec("git", ["rev-parse", "--verify", `origin/\$\{normalizedBranchName}`]);
await exec.exec("git", ["checkout", "-B", normalizedBranchName, ...]);
await exec.exec("git", ["push", "origin", normalizedBranchName]);

targetFileName is sourced from agent output JSON (loadAgentOutput()result.itemsasset.targetFileName) with no path or character sanitization applied before the exec call. A targetFileName containing " could break out of quoting; one containing ;, &&, or backticks could permit command injection.

Forensics Analysis:

  • Line 156 introduced in commit 17ca20b8 by Copilot on 2025-12-23 ("Remove inline mode and externalize all scripts via setup action")
  • Partial fix attempted in commit d07e64c3 by Copilot on 2026-02-20 ("fix: supply chain and shell injection security findings") — but this line was missed
  • No further fix commits since then

Remediation Task:

  • Task 1 — Convert line 156 of actions/setup/js/upload_assets.cjs to use the safe array form:
    // Change from:
    await exec.exec(`git add "\$\{targetFileName}"`);
    // Change to:
    await exec.exec("git", ["add", targetFileName]);
    This is consistent with the existing pattern used in the rest of the file after commit d07e64c3.

Finding 2 — DYNAMIC EXEC (Low / Mitigated)

Location: actions/setup/js/push_to_pull_request_branch.cjs:312 and actions/setup/js/create_pull_request.cjs:568

Description: exec.exec(\git am ${patchFilePath}`)uses template string interpolation. However,patchFilePathis **internally generated** ingenerate_git_patch.cjs` via:

function getPatchPath(branchName) {
  const sanitized = sanitizeBranchNameForPatch(branchName);
  return `/tmp/gh-aw/aw-\$\{sanitized}.patch`;
}
// sanitizeBranchNameForPatch removes: / \ : * ? " < > |
// Result is always: /tmp/gh-aw/aw-(alphanumeric-dash-chars).patch

The sanitization constrains the path to characters safe for shell interpolation. No actionable fix required, but converting to array form would be defensive best practice.

Forensics: Introduced in commit b58fd691 by Copilot on 2026-02-21.

Recommendation (non-urgent):

  • Consider converting to exec.exec("git", ["am", patchFilePath]) for consistency with the safe pattern used elsewhere in the codebase.

Finding 3 — SHELL EVAL IN TEST HELPER (Negligible / Accepted Risk)

Location: actions/setup/sh/clean_git_credentials_test.sh:34

Description: eval "\$\{condition}" is used in a test-only assert() helper function. All current callers pass hard-coded string literals. No external input reaches this eval.

Forensics: Introduced in commit 45f92f64 by Copilot on 2026-02-19 ("Recursively clean git credentials from all checkouts in workspace and /tmp/").

Recommendation: Low priority. Could be refactored to use a safer assertion mechanism if the test file evolves.


Techniques Executed (Full Comprehensive)

Technique Results Detail
Technique Status Notes
Pattern Analysis Complete 1 confirmed finding (upload_assets), 2 mitigated
AST Inspection No findings No suspicious function names, no unusual exports
Entropy Analysis No findings No obfuscated/encoded strings
Network Analysis No findings validate_secrets.cjs makes expected API validation calls; all other URLs are docs refs or GitHub domains
Behavioral Analysis No findings Date logic is timestamps/expiry guards only; no time bombs; no persistence
Dependency Audit No findings No path traversal in require(); no known-compromised packages
False Positives Investigated and Dismissed
  • validate_secrets.cjs API calls — Legitimate diagnostic tool (maintenance workflow); calls api.anthropic.com, api.openai.com, api.search.brave.com, api.notion.com only to validate status codes of configured secrets. Only HTTP status codes are returned; key values are never logged or exfiltrated.
  • Buffer.from(..., "base64") — Decodes GitHub API file contents (standard API pattern).
  • String.fromCharCode() — Unicode normalization in sanitize_content_core.cjs, not obfuscation.
  • IP 172.30.0.1 — Documented internal Docker network gateway in convert_gateway_config_codex.sh.
  • patchFilePath template exec — Internally generated sanitized path /tmp/gh-aw/aw-*.patch.

Next Steps

@pelikhan

  1. Fix: Apply remediation for Finding 1 — convert upload_assets.cjs:156 to the safe array form (1-line change)
  2. Optional: Harden push_to_pull_request_branch.cjs:312 and create_pull_request.cjs:568 by converting to array form for defensive consistency
  3. Monitor: No new backdoors, secret exfiltration, or destructive code detected in this full scan

References:

  • §22279189887
  • Security fix commit: d07e64c3 ("fix: supply chain and shell injection security findings", 2026-02-20)

Generated by Daily Security Red Team Agent

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions