Skip to content

Build1 publisherNot yet confirmed elsewhere2 min readPublished

The --config flag reopens a simple-git code-execution bug that was patched in 2022

CVE-2026-6951 reopens remote code execution in simple-git, a library downloaded 8.7 million times a week, by respelling the blocked -c flag as --config. The 2022 patch never checked the long form, so the same attack works wherever untrusted input reaches a git call.

The Engineer · Build desk

Drafted by a language model from the sources cited here and checked against its claim ledger before publication. How we use AISend a correction

What happened

  • CVE-2026-6951 is an incomplete fix for CVE-2022-25912, the option-injection remote-code-execution flaw that simple-git patched in 2022.
  • The 2022 guard, preventProtocolOverride in block-unsafe-operations-plugin.ts, compares each argument against the exact string -c and sees nothing else.
  • simple-git reports 7,789 packages that depend on it, so the flaw sits under a large slice of the JavaScript build chain.
  • simple-git forwards the options or customArgs array that callers pass to clone() and fetch() to the git binary almost verbatim.
  • A sibling flaw, CVE-2026-28292, slips past the same regex with uppercase PROTOCOL.ALLOW because the original pattern was case-sensitive.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • constraint No exact-match filter can be trusted as a security boundary against git's command line, because the guard it was tested against checks -c but not --config or uppercase forms.
  • exposure Any application that folds user input or an API response into simple-git's options array is exploitable again, not only code that obviously handles git.
  • decision Shops that treated CVE-2022-25912 as closed have to reopen it, patch simple-git, and re-check any argument blocklist of their own for untested synonyms.

Code execution through this bug needs two injected pieces. The first is the config value `protocol.ext.allow=always`; the second is a clone URL that begins with `ext::` [9]. git's `ext::` transport exists to reach a repository through an external helper program, except that the helper slot runs whatever shell command you put there [7]. The transport ships disabled, and setting `protocol.ext.allow=always` is what turns it on [8]. git's own documentation shows the shape: clone `ext::sh -c touch% /tmp/pwned% >&2` and a file appears under /tmp [13]. On a host that runs builds or deploys, code runs on the build host [1].

git routes `-c` and `--config` through the same parser inside the binary, so to the running process they are one option [12]. A filter that matches argument strings sits one layer above that parser and never inspects the option git will actually run. To be complete, such a filter would have to list every spelling git accepts for one feature: short and long flags, uppercase, `=`-joined forms [15]. Miss any one and the check does nothing. In my view a fix should pass only the arguments a call is allowed to use and reject the rest.

The analysis does not name a fixed simple-git release or a disclosure date. If and when a corrected version ships, the check to confirm in its changelog is one that covers `--config` as well as `-c`.

What to watch

  • Whether maintainers replace the -c blocklist with an allowlist of the git arguments each call is permitted to pass.
  • Further CVEs in the same block-unsafe-operations plugin from flag spellings the filter never tested.
  • Downstream advisories from packages that pass external strings into simple-git clone and fetch calls.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories