CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-28291
8.1

CVE-2026-28291: Command Execution via Option-Parsing Bypass in simple-git

Amit Schendel
Amit Schendel
Senior Security Researcher

Apr 13, 2026·7 min read·5 visits

PoC Available

Executive Summary (TL;DR)

A flaw in simple-git < 3.32.0 allows arbitrary code execution via Git short-option bundling (e.g., `-vu`), bypassing regex-based security filters designed to block dangerous options like `-u`.

CVE-2026-28291 is a high-severity OS command injection vulnerability in the simple-git (git-js) library, resulting from an incomplete remediation of CVE-2022-25860. The vulnerability allows attackers to bypass regex-based security filters using Git's short-option bundling, leading to arbitrary command execution on the host system.

Vulnerability Overview

The simple-git library provides a programmatic interface for Node.js applications to execute native Git commands. The library constructs child processes using arguments supplied by the calling application. When user-controlled input is passed into methods such as clone, fetch, or push, the library relies on a security plugin to filter out dangerous Git arguments that can trigger external command execution.

CVE-2026-28291 is classified as CWE-78 (OS Command Injection) and represents an incomplete patch for a previous vulnerability tracked as CVE-2022-25860. The library attempts to block specific command-line flags, such as --upload-pack and its short form -u. However, the implementation of this filter assumes a strict, standalone format for these flags.

Because Git's internal CLI parser accepts multiple short options bundled behind a single hyphen, the library's filtering mechanism fails to identify dangerous flags when combined with innocuous ones. An attacker exploiting this discrepancy can successfully inject malicious arguments into the Git child process.

The successful exploitation of this flaw results in arbitrary command execution within the context of the Node.js application. This allows an attacker to interact directly with the underlying operating system, potentially leading to unauthorized data access or complete system compromise.

Root Cause Analysis

The vulnerability originates in the block-unsafe-operations-plugin.ts file, where simple-git utilizes a plugin-based architecture to intercept and validate Git commands before execution. The plugin maintains a blocklist of flags known to facilitate arbitrary command execution via external helpers. The blocked flags include --upload-pack, --receive-pack, --exec, and the short alias -u.

The validation logic relies on regular expressions to identify these flags within the arguments array. The regex designed to catch the -u flag is implemented as /^\s*-u\b/. This expression enforces a requirement that the string either begins with -u or contains it as a standalone word boundary. It functions correctly when an application passes ["-u", "payload"] as arguments.

The logic fails to account for the behavior of Git's internal option parser (parse-options.c). Git supports short-option bundling, allowing multiple single-character flags to be grouped under a single hyphen. For example, the command git clone -vu ... is interpreted by the Git binary identically to git clone -v -u ....

When an attacker provides -vu as an argument, the simple-git regex evaluates the string and returns false, as the -u character does not follow a space or exist at a word boundary. The library passes the -vu string unmodified to the Git binary. Git subsequently unpacks the bundled options, recognizes the -u flag, and executes the specified command.

Code Analysis

The vulnerable code resides in the option-blocking plugin of the simple-git repository. The library processes user input by iterating over an array of arguments and applying a series of regular expressions to determine if any argument matches a known-bad pattern.

// Vulnerable blocklist implementation
const UNSAFE_OPTIONS = [
  /^\s*--upload-pack\b/,
  /^\s*--receive-pack\b/,
  /^\s*--exec\b/,
  /^\s*-u\b/ // Vulnerable regex targeting only standalone -u
];
 
export function blockUnsafeOperationsPlugin(args: string[]) {
  for (const arg of args) {
    for (const regex of UNSAFE_OPTIONS) {
      if (regex.test(arg)) {
        throw new Error('Unsafe option detected');
      }
    }
  }
}

The code block above demonstrates the flawed approach of using static string matching to parse complex CLI semantics. Because the regex relies on \b (word boundary) and exact positional matching, any string modification that remains valid in Git but alters the regex matching conditions will bypass the filter.

// Example of how the fix is structurally implemented in 3.32.0
export function blockUnsafeOperationsPlugin(args: string[], config: Config) {
  if (config.allowUnsafePack) return;
 
  for (const arg of args) {
    if (arg.startsWith('--upload-pack') || arg.startsWith('--receive-pack')) {
       throw new Error('Unsafe option detected');
    }
    
    // Account for Git short-option bundling
    if (arg.startsWith('-') && !arg.startsWith('--')) {
       if (arg.includes('u')) {
           throw new Error('Unsafe bundled option detected');
       }
    }
  }
}

The patch addresses the fundamental parsing discrepancy by inspecting the individual characters within any argument that begins with a single hyphen. Furthermore, version 3.32.0 introduces the allowUnsafePack explicit configuration option. By defaulting to a restrictive posture and implementing more comprehensive parsing logic, the library neutralizes the short-option bundling vector.

Exploitation Mechanics

Exploitation requires the attacker to have influence over the arguments passed to a simple-git method. This typically occurs in applications that allow users to specify repository URLs or custom branch names, which the application then blindly appends to the Git command structure.

To exploit the vulnerability, the attacker constructs a payload utilizing the bundled -u option. A common proof-of-concept payload targets the clone command: git clone -vu /tmp/malicious.sh https://example.com/repo.git. The application accepts -vu and /tmp/malicious.sh as arguments and passes them to the library.

Once the command executes, the Git binary parses -vu. It enables verbose output (-v) and sets the upload-pack program path (-u). When Git attempts to negotiate the packfile transfer, it spawns a secondary process using the file path provided immediately after the options, executing the attacker's script.

Re-exploitation and Variant Analysis

The reliance on blocklists for command-line parsing introduces inherent fragility. During the research of this vulnerability, several other parsing discrepancies between generic regex filters and Git's internal CLI logic were identified. These variants demonstrate why string-matching is generally insufficient for CLI security.

Git permits the abbreviation of long options as long as the provided prefix is unambiguous. An attacker could potentially bypass exact string matches by supplying --upload-pac or --receive-pa. The Git binary expands these abbreviations to their full form, while a rigid blocklist ignores them.

Git also supports sticky arguments and equal sign delimiters. Options can be followed immediately by their values without a separating space (e.g., -u/path/to/shell), or assigned via an equals sign (--upload-pack=cmd). Regex implementations expecting whitespace delimiters will fail to match these inputs.

Additionally, the -c flag allows users to pass arbitrary configuration variables at runtime. Attackers can use this vector to modify Git's behavior, such as redefining core hooks or enabling vulnerable protocols (e.g., ext::), which entirely circumvents the --upload-pack restrictions.

Impact Assessment

The successful exploitation of CVE-2026-28291 results in full remote code execution (RCE) on the host running the Node.js application. The injected commands execute with the same privileges as the Node.js process itself, making the severity dependent on the deployment environment.

The vulnerability carries a CVSS v3.1 base score of 8.1. The attack complexity is rated as High because the attacker must find a specific application feature that passes user input directly into the simple-git arguments array without preceding sanitization. The vulnerability requires no authentication and no user interaction.

An attacker who gains execution can exfiltrate sensitive data, manipulate internal databases, or establish a persistent backdoor on the host system. In containerized environments, the compromise may allow the attacker to pivot and launch attacks against internal network resources or the orchestrator control plane.

Remediation and Mitigation

The primary remediation for CVE-2026-28291 is upgrading the simple-git package to version 3.32.0 or higher. This release contains robust parsing logic that accurately accounts for Git short-option bundling and other CLI irregularities. It also shifts the API design to require explicit developer opt-in for dangerous options.

If immediate patching is not feasible, development teams must manually sanitize all user-supplied input before passing it to simple-git. Input validation must enforce strict allowlists, ensuring that strings only contain alphanumeric characters and safely encoded URL structures. Any input beginning with a hyphen should be rejected outright.

From an architectural standpoint, applications should avoid constructing Git commands using untrusted data. When interacting with user-specified repositories, developers should pass arguments as explicit parameters rather than arrays of raw CLI flags, ensuring that positional arguments cannot be misinterpreted as options by the underlying Git binary.

Official Patches

steveukxRelease Notes (3.32.0)

Fix Analysis (1)

Technical Appendix

CVSS Score
8.1/ 10
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H

Affected Systems

Node.js applications utilizing the simple-git libraryCI/CD pipelines and deployment scripts relying on git-js for repository management

Affected Versions Detail

Product
Affected Versions
Fixed Version
git-js (simple-git)
steveukx
< 3.32.03.32.0
AttributeDetail
CWE IDCWE-78
Attack VectorNetwork
CVSS Score8.1
ImpactHigh (Remote Code Execution)
Exploit StatusProof of Concept
CISA KEVFalse

MITRE ATT&CK Mapping

T1059Command and Scripting Interpreter
Execution
CWE-78
Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')

The software constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command.

Vulnerability Timeline

CVE-2022-25860 (original command injection) discovered.
2022-01-23
Preliminary analysis of bypasses and potential fixes (Commit 789c13e).
2025-06-06
CVE-2026-28291 published and officially fixed in version 3.32.0.
2026-04-13

References & Sources

  • [1]Official Advisory
  • [2]Vulnerable Code Location
  • [3]Release Notes (3.32.0)
  • [4]CVE Record (CVE-2026-28291)
  • [5]Related Vulnerability (CVE-2022-25860)
Related Vulnerabilities
CVE-2022-25860

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.