DEV Community

Amartya Jha
Amartya Jha

Posted on • Originally published at codeant.ai

CVE-2026-28292: How a Simple Case-Sensitivity Bug Turns simple-git Into a Remote Code Execution Weapon (CVSS 9.8)

TL;DR

A critical vulnerability (CVSS 9.8) in simple-git — one of the most popular Node.js Git libraries with millions of weekly downloads — allows attackers to achieve full remote code execution by simply changing the casing of a config key. Yes, you read that right. Uppercase letters broke the security model.

This vulnerability, discovered by CodeAnt AI Security Research, bypasses two previously patched RCE flaws and affects versions 3.15.0 through 3.32.2.


The Background: A History of RCE in simple-git

To understand CVE-2026-28292, we need to look at the vulnerabilities that came before it.

CVE-2022-25912: The ext: Protocol Attack

Git supports an ext:: transport protocol that allows executing arbitrary external commands. In 2022, researchers discovered that simple-git's clone() method could be abused to execute arbitrary shell commands:

const simpleGit = require('simple-git');
const git = simpleGit();

// Malicious clone using ext: protocol
git.clone(
  'ext::sh -c touch% /tmp/pwned% >&2',
  '/tmp/target-repo',
  ["-c", "protocol.ext.allow=always"]
);
Enter fullscreen mode Exit fullscreen mode

This worked because an attacker could pass -c protocol.ext.allow=always as a Git config override, enabling the dangerous ext: protocol and allowing arbitrary command execution through the remote URL.

Fix: simple-git introduced the blockUnsafeOperationsPlugin in version 3.15.0, which scans arguments for dangerous config overrides like protocol.ext.allow before executing Git commands.

CVE-2022-25860: Incomplete Sanitization

Shortly after, researchers found that the sanitization was incomplete — the plugin didn't cover all methods. Functions like pull(), push(), and listRemote() were still vulnerable.

Fix: Extended the blockUnsafeOperationsPlugin to cover additional methods in version 3.16.0.


CVE-2026-28292: The Case-Sensitivity Bypass

Here's where it gets interesting — and embarrassingly simple.

The blockUnsafeOperationsPlugin was designed to detect and block dangerous Git config overrides. It checks for arguments like:

-c protocol.ext.allow=always
Enter fullscreen mode Exit fullscreen mode

But here's the critical flaw: the check was case-sensitive, while Git config keys are case-insensitive.

Git's configuration system treats keys in a case-insensitive manner. This means the following are all equivalent to Git:

protocol.ext.allow=always
Protocol.Ext.Allow=always
PROTOCOL.EXT.ALLOW=always
protocol.EXT.allow=always
Enter fullscreen mode Exit fullscreen mode

But simple-git's security plugin only checked for the lowercase version. An attacker simply needed to capitalize one or more characters in the config key to completely bypass the protection:

const simpleGit = require('simple-git');
const git = simpleGit();

// Bypass blockUnsafeOperationsPlugin with uppercase letters
git.clone(
  'ext::sh -c touch% /tmp/pwned% >&2',
  '/tmp/target-repo',
  ["-c", "Protocol.ext.Allow=always"]  // Case-sensitivity bypass!
);
Enter fullscreen mode Exit fullscreen mode

That's it. One uppercase letter is all it takes to bypass the security plugin and achieve full remote code execution.


Why This Is Critical

CVSS 9.8 — It Doesn't Get Much Worse

Metric Value
Attack Vector Network
Attack Complexity Low
Privileges Required None
User Interaction None
Confidentiality Impact High
Integrity Impact High
Availability Impact High

Massive Blast Radius

simple-git is used extensively in:

  • CI/CD pipelines — build systems that clone repositories
  • Developer tools — IDEs, code editors, and Git GUIs
  • Web applications — platforms that interact with Git repos
  • Automation scripts — deployment and DevOps tooling

Any application that passes user-controlled input to simple-git's clone(), pull(), push(), or listRemote() methods is potentially vulnerable.


The Lesson: Defense in Depth and Case Normalization

This CVE is a textbook example of why input normalization must happen before validation. The fix is straightforward — normalize the config key to lowercase before checking it against the blocklist.

But the deeper lesson is about understanding the security model of the tools you wrap. Git treats config keys as case-insensitive. Any security layer built on top of Git must respect that behavior, or it creates a gap that attackers will exploit.

Key Takeaways for Developers:

  1. Always normalize input before validation — case, encoding, whitespace, Unicode
  2. Understand the security model of underlying tools — if Git is case-insensitive, your filter must be too
  3. Don't assume previous patches are complete — this is the third bypass of the same attack vector
  4. Use allowlists over blocklists when possible — instead of blocking dangerous protocols, only allow known-safe ones

Affected Versions & Remediation

Detail Value
CVE ID CVE-2026-28292
Affected Package simple-git (npm)
Affected Versions 3.15.0 – 3.32.2
Fixed Version 3.23.0+
CVSS Score 9.8 (Critical)
CWE CWE-78 (OS Command Injection)

Immediate Actions:

# Check your current version
npm list simple-git

# Update to the latest version
npm install simple-git@latest
Enter fullscreen mode Exit fullscreen mode

If you cannot update immediately, audit your codebase for any place where user-controlled input flows into simple-git method arguments.


Disclosure Timeline

  • Discovered by: CodeAnt AI Security Research
  • Published: March 10, 2026
  • Severity: Critical (CVSS 9.8)

About CodeAnt AI

CodeAnt AI is an AI-powered code review platform that auto-fixes code quality and security issues across 30+ languages. Our security research team continuously identifies vulnerabilities in widely-used open source packages to make the software ecosystem safer.

Read more of our security research at codeant.ai/security-research.


This vulnerability was discovered and responsibly disclosed by the CodeAnt AI Security Research team.

Top comments (0)