Описание
simple-git has blockUnsafeOperationsPlugin bypass via case-insensitive protocol.allow config key enables RCE
Summary
The blockUnsafeOperationsPlugin in simple-git fails to block git protocol
override arguments when the config key is passed in uppercase or mixed case.
An attacker who controls arguments passed to git operations can enable the
ext:: protocol by passing -c PROTOCOL.ALLOW=always, which executes an
arbitrary OS command on the host machine.
Details
The preventProtocolOverride function in
simple-git/src/lib/plugins/block-unsafe-operations-plugin.ts (line 24)
checks whether a -c argument configures protocol.allow using this regex:
This regex is case-sensitive. Git treats config key names
case-insensitively — it normalises them to lowercase internally.
As a result, passing PROTOCOL.ALLOW=always, Protocol.Allow=always,
or any mixed-case variant is not matched by the regex, the check
returns without throwing, and git is spawned with the unsafe argument.
Verification that git normalises the key:
The fix is a single character — add the /i flag:
poc.js
Test Results
Vector 1 — Original CVE-2022-25912 (protocol.ext.allow=always, lowercase)
Result: BLOCKED ✅
The original Snyk PoC payload using lowercase protocol.ext.allow=always is correctly intercepted by preventProtocolOverride before git is invoked. A GitPluginError is thrown immediately and the sentinel file is never created.
Output:
Vector 2 — Uppercase bypass (PROTOCOL.ALLOW=always)
Result: BYPASSED ⚠️ — RCE confirmed
The preventProtocolOverride regex /^\s*protocol(.[a-z]+)?.allow/ is case-sensitive. PROTOCOL.ALLOW=always (uppercase) passes the check without error. Git normalises config key names to lowercase internally, enabling the ext:: protocol. The injected shell command executes before git errors on the missing repository stream.
Output:
/tmp/pwn-codeant was created by the git subprocess — command execution confirmed.
Vector 3 — Real-world scenario (target: https://github.com/CodeAnt-AI/codeant-quality-gates)
Result: BYPASSED ⚠️ — RCE confirmed
An application passes user-controlled customArgs to simpleGit().clone(). The attacker injects PROTOCOL.ALLOW=always and substitutes a malicious ext:: URL in place of the intended repository URL. The plugin does not block the uppercase variant; git enables ext:: and executes the payload before the application can detect the failure.
Output:
/tmp/pwn-realworld was created — arbitrary command execution in a realistic application context confirmed.
Summary
| # | Vector | Payload | Sentinel file | Result |
|---|---|---|---|---|
| 1 | CVE-2022-25912 original | protocol.ext.allow=always (lowercase) | not created | Blocked ✅ |
| 2 | Case-sensitivity bypass | PROTOCOL.ALLOW=always (uppercase) | /tmp/pwn-codeant created | RCE ⚠️ |
| 3 | Real-world app scenario | PROTOCOL.ALLOW=always + attacker URL | /tmp/pwn-realworld created | RCE ⚠️ |
The case-sensitive regex in preventProtocolOverride blocks protocol.*.allow but does not account for uppercase or mixed-case variants. Git accepts all variants identically due to case-insensitive config key normalisation, allowing full bypass of the protection in all versions of simple-git that carry the 2022 fix.
/tmp/pwned is created by the git subprocess via the ext:: protocol.
All of the following bypass the check:
Argument passed via -c | Regex matches? | Git honours it? |
|---|---|---|
protocol.allow=always | ✅ blocked | ✅ |
PROTOCOL.ALLOW=always | ❌ bypassed | ✅ |
Protocol.Allow=always | ❌ bypassed | ✅ |
PROTOCOL.allow=always | ❌ bypassed | ✅ |
protocol.ALLOW=always | ❌ bypassed | ✅ |
Impact
Any application that passes user-controlled values into the customArgs
parameter of clone(), fetch(), pull(), push() or similar simple-git
methods is vulnerable to arbitrary command execution on the host machine.
The ext:: git protocol executes an arbitrary binary as a remote helper.
With protocol.allow=always enabled, an attacker can run any OS command
as the process user — full read, write and execution access on the host.
Пакеты
simple-git
>= 3.15.0, < 3.32.3
3.32.3
Связанные уязвимости
A vulnerability was discovered in the simple-git Node.js library. The issue is caused by improper validation of user-supplied input when constructing Git commands. An attacker able to supply specially crafted repository URLs or arguments could exploit Git’s ext:: protocol handler to execute arbitrary commands on the underlying system. This flaw bypasses earlier mitigations intended to restrict unsafe Git protocols. By injecting configuration options that re-enable the ext:: protocol, an attacker could cause the application to execute arbitrary external commands through the Git client. If a vulnerable application passes untrusted input to simple-git operations such as repository cloning or fetching, a remote attacker could exploit this flaw to execute arbitrary commands on the host system with the privileges of the application process.
`simple-git`, an interface for running git commands in any node.js application, has an issue in versions 3.15.0 through 3.32.2 that allows an attacker to bypass two prior CVE fixes (CVE-2022-25860 and CVE-2022-25912) and achieve full remote code execution on the host machine. Version 3.23.0 contains an updated fix for the vulnerability.