Skip to content

fix(core): prevent git option injection via CI branch names (GHSA-v58q-fvq4-9vh4) - #378

Merged
gregberge merged 1 commit into
mainfrom
fix/git-option-injection
Sep 11, 2026
Merged

gregberge merged 1 commit into
mainfrom
fix/git-option-injection

Conversation

@gregberge

Copy link
Copy Markdown
Member

Description

Fixes GHSA-v58q-fvq4-9vh4 (CWE-88, argument injection) in @argos-ci/core.

The git helpers of the CI environment pass the branch and commit they get from CI to git as positional arguments. Git parses any argument starting with a dash as an option: a pull request opened from a branch named --upload-pack=<command> (a valid, pushable ref name) made git fetch run <command> through a shell on ssh:// and file:// origins, whenever the merge base is resolved locally (projects without a connected Git provider). The fix for GHSA-4x45-gxvp-6283 (#319) removed the shell but left this option parsing in place.

Changes

  • Every git invocation receiving a CI-provided branch or commit now passes it after --end-of-options (git 2.24+, November 2019), so git always treats it as a ref: fetch, merge-base, rev-parse, log and rev-list.
  • The fetch helper assembles the argument list itself (options, then --end-of-options origin, then refs), so no caller can leave the separator out.
  • A note at the top of git.ts records both hardening rules with the advisory IDs.

Rejecting names starting with a dash was the alternative. The terminator was preferred because it keeps legitimately named branches working. On git older than 2.24 the commands fail on the unknown option before contacting the remote, so the failure is closed rather than exploitable.

Tests

The single shell-injection test is replaced with a block covering both advisories:

  • three tests push the advisory's --upload-pack payload through the merge base, the ancestor listing and the commit parents, and assert the injected command never runs;
  • one test pushes a branch named -dashed to origin and checks it is fetched and used as the merge-base head.

Against the unfixed code, the four new tests fail and the injected command runs from all three sinks. With the fix, the full @argos-ci/core suite passes (148 tests, 2 pre-existing skips), and tsc, eslint and prettier are clean.

Type of changes

bug

Checklist

  • I have read the CONTRIBUTING doc
  • The commits message follows the Conventional Commits' policy
  • Lint and unit tests pass locally
  • I have added tests if needed

Optional checks:

  • My changes requires a change to the documentation
  • I have updated the documentation accordingly

Further comments

Reported by @manus-use. Once merged, @argos-ci/core should be released and the new version set as the patched version on the advisory, which currently lists none.

🤖 Generated with Claude Code

…q-fvq4-9vh4)

The git helpers pass the branch and commit of the CI environment to git as
positional arguments. Git parses any argument starting with a dash as an
option, so a pull request from a branch named `--upload-pack=<command>` (a
valid, pushable ref name) made `git fetch` run `<command>` through a shell on
ssh:// and file:// origins whenever the merge base is resolved locally, i.e.
for projects without a connected Git provider. The fix for
GHSA-4x45-gxvp-6283 removed the shell but left this option parsing.

Pass every CI-provided value after `--end-of-options` (git 2.24+) in the
fetch, merge-base, rev-parse, log and rev-list invocations, so git always
treats it as a ref. The fetch helper now assembles the argument list itself
so no caller can leave the separator out.

Add regression tests feeding the advisory's payload through the merge base,
the ancestor listing and the commit parents, plus one checking that a branch
legitimately named with a leading dash is still fetched.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@gregberge gregberge added the bug Something isn't working label Sep 11, 2026
@vercel

vercel Bot commented Sep 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
argos-js-sdk-reference Ready Ready Preview Sep 11, 2026 2:04pm UTC

Request Review

@gregberge
gregberge requested a review from jsfez September 11, 2026 19:04
@gregberge
gregberge merged commit 67f24a9 into main Sep 11, 2026
98 of 99 checks passed
@gregberge
gregberge deleted the fix/git-option-injection branch September 11, 2026 19:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant