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.