CVE-2026-102827: simple-git Unsafe-operations Plugin Bypass Vulnerability

HIGH
Advisory Identifier: GHSA-858h-whjf-mvg5
CVSS 8.1
CWE-88 CWE-77
Published
Advisory Summary

CVE-2026-102827 is a HIGH (CVSS 8.1) unsafe-operations plugin bypass vulnerability (CWE-88: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection')) affecting simple-git libraries in the npm ecosystem. The issue involves unsafe-operations plugin bypass via git long-option abbreviation (--receive-p/--exe) -> command execution (residual of cve-2026-28291). Remediation is available by upgrading affected packages to version 4.0.0.

CVE-2026-102827 at a Glance

CVE Identifier CVE-2026-102827
GHSA Identifier GHSA-858h-whjf-mvg5
Severity HIGH
CVSS v3.1 Base Score 8.1
CWE Classification CWE-88: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection')
Affected Product simple-git
Package Ecosystem npm
Published Date
Last Updated

Security Impact

CVSS: 8.1

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H).

Attack Vector Network (AV:N)
Attack Complexity High (AC:H)
Privileges Required None (PR:N)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality High (C:H)
Integrity High (I:H)
Availability High (A:H)

How to Fix CVE-2026-102827

To remediate this vulnerability, upgrade all affected simple-git dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

simple-git fixed: 4.0.0
npm install simple-git@4.0.0
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

npm ls simple-git

How to Check if You Are Affected

To determine whether your Node.js application is affected by CVE-2026-102827, inspect your project dependencies using npm:

npm ls simple-git

Analyze the terminal output to locate any version of simple-git in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 4.0.0), your application is affected.

Note: The npm ls simple-git command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-88: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection'), where the product constructs a string for a command to be executed by a separate component in another control sphere, but it does not properly delimit the intended arguments, options, or switches within that command string. In simple-git, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

simple-git's blockUnsafeOperationsPlugin blocks dangerous git options (--upload-pack/--receive-pack/--exec/...) unless the consumer opts in via unsafe:{allowUnsafePack:true}. Detection (@simple-git/argv-parser detectVulnerableFlags) matches the parsed flag NAME against literal-spelling patterns: /--(upload|receive)-pack/ (requires the literal '-pack') and the string '--exec'. But git accepts unambiguous prefix abbreviations of long options, and expandToken (token-expander.ts) returns the LITERAL token as flag.name (it uses the spec only for needsNext, never to canonicalize). So `git push --receive-p=<cmd>` parses with flag.name='--receive-p', which /--(upload|receive)-pack/ does NOT match, yet git expands --receive-p -> --receive-pack and runs <cmd> (on a local/file remote, locally). The clone side is robust (its '--u' substring rule catches every --upload* abbreviation); the push --receive-* and --exe* abbreviations have no equivalent rule and slip through. Proof of concept (latest: simple-git 3.36.0, @simple-git/argv-parser 1.1.1, default unsafe plugin ON): Gate vulnerabilityCheck: 'push --receive-pack=touch...' -> BLOCKED; 'push --receive-pa=touch...' and 'push --receive-p=touch...' -> BYPASS (empty vulns); '--exec=' BLOCKED, '--exe=' BYPASS. End-to-end via simpleGit().push(): CONTROL git.push(['../bare','HEAD:refs/heads/c','--receive-pack=touch /tmp/pwned_ctrl;']) -> throws GitPluginError 'Use of --upload-pack or --receive-pack is not permitted...'; no command runs. BYPASS git.push(['../bare','HEAD:refs/heads/e2e','--receive-p=touch /tmp/pwned_e2e;']) -> NO GitPluginError; /tmp/pwned_e2e CREATED (git executed the injected command); only a later GitError surfaces. Direct git confirms `git push ../bare --receive-p='touch X;' HEAD:refs/heads/m` and `--exe='touch Y;'` both execute on a local/path remote. Impact: any app relying on simple-git's default unsafe-operations protection while passing attacker-influenced options/args into a git push (local/file remote, or attacker-influenced receive-pack target) can be made to execute arbitrary commands -- the exact protection CVE-2026-28291 provided, defeated by an abbreviated spelling. Same class/impact as GHSA-jcxm-m3jx-f287, on the push path. Remediation: canonicalize git option abbreviations before matching (resolve to the canonical long name via the per-task flag spec in expandToken), or match on the option stem/prefix down to the shortest unambiguous form for push receive-pack/exec (mirroring the clone-side '--u' approach). Also audit --template and -c/config-write detection for the same abbreviation gap. Credit: anir0y (independent security research).

CVE-2026-102827 Affected simple-git Versions

1 component(s)
Fixed Versions:
4.0.0
Product / Package Ecosystem Affected Versions Fixed Version
simple-git
npm
< 4.0.0
4.0.0

References

Frequently Asked Questions

What is CVE-2026-102827?
CVE-2026-102827 is a security vulnerability in simple-git involving unsafe-operations plugin bypass via git long-option abbreviation (--receive-p/--exe) -> command execution (residual of CVE-2026-28291) under CWE-88: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection').
Which simple-git versions are affected?
Affected versions include releases prior to 4.0.0 across affected packages: simple-git.
What version fixes CVE-2026-102827?
Upgrading to 4.0.0 (or the latest patched release for your respective branch) resolves the vulnerability.
Is simple-git affected?
Yes, simple-git is affected in releases prior to 4.0.0. Upgrade your dependency to 4.0.0 or later.
What is the CVSS score of CVE-2026-102827?
CVE-2026-102827 has a CVSS v3.1 base score of 8.1 (HIGH) with vector string CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H.
What CWE is associated with CVE-2026-102827?
CVE-2026-102827 is classified under CWE-88: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection') (The product constructs a string for a command to be executed by a separate component in another control sphere, but it does not properly delimit the intended arguments, options, or switches within that command string.).
How can I check npm dependencies for CVE-2026-102827?
Run the dependency tree command: 'npm ls simple-git'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-858h-whjf-mvg5",
  "modified" : "2026-10-05T23:47:58Z",
  "published" : "2026-10-05T23:47:58Z",
  "aliases" : [ "CVE-2026-102827" ],
  "summary" : "simple-git: unsafe-operations plugin bypass via git long-option abbreviation (--receive-p/--exe) -> command execution (residual of CVE-2026-28291)",
  "details" : "simple-git's blockUnsafeOperationsPlugin blocks dangerous git options (--upload-pack/--receive-pack/--exec/...) unless the consumer opts in via unsafe:{allowUnsafePack:true}. Detection (@simple-git/argv-parser detectVulnerableFlags) matches the parsed flag NAME against literal-spelling patterns: /--(upload|receive)-pack/ (requires the literal '-pack') and the string '--exec'. But git accepts unambiguous prefix abbreviations of long options, and expandToken (token-expander.ts) returns the LITERAL token as flag.name (it uses the spec only for needsNext, never to canonicalize). So `git push --receive-p=<cmd>` parses with flag.name='--receive-p', which /--(upload|receive)-pack/ does NOT match, yet git expands --receive-p -> --receive-pack and runs <cmd> (on a local/file remote, locally). The clone side is robust (its '--u' substring rule catches every --upload* abbreviation); the push --receive-* and --exe* abbreviations have no equivalent rule and slip through.\n\nProof of concept (latest: simple-git 3.36.0, @simple-git/argv-parser 1.1.1, default unsafe plugin ON):\nGate vulnerabilityCheck: 'push --receive-pack=touch...' -> BLOCKED; 'push --receive-pa=touch...' and 'push --receive-p=touch...' -> BYPASS (empty vulns); '--exec=' BLOCKED, '--exe=' BYPASS.\nEnd-to-end via simpleGit().push():\n  CONTROL git.push(['../bare','HEAD:refs/heads/c','--receive-pack=touch /tmp/pwned_ctrl;']) -> throws GitPluginError 'Use of --upload-pack or --receive-pack is not permitted...'; no command runs.\n  BYPASS  git.push(['../bare','HEAD:refs/heads/e2e','--receive-p=touch /tmp/pwned_e2e;']) -> NO GitPluginError; /tmp/pwned_e2e CREATED (git executed the injected command); only a later GitError surfaces.\nDirect git confirms `git push ../bare --receive-p='touch X;' HEAD:refs/heads/m` and `--exe='touch Y;'` both execute on a local/path remote.\n\nImpact: any app relying on simple-git's default unsafe-operations protection while passing attacker-influenced options/args into a git push (local/file remote, or attacker-influenced receive-pack target) can be made to execute arbitrary commands -- the exact protection CVE-2026-28291 provided, defeated by an abbreviated spelling. Same class/impact as GHSA-jcxm-m3jx-f287, on the push path.\n\nRemediation: canonicalize git option abbreviations before matching (resolve to the canonical long name via the per-task flag spec in expandToken), or match on the option stem/prefix down to the shortest unambiguous form for push receive-pack/exec (mirroring the clone-side '--u' approach). Also audit --template and -c/config-write detection for the same abbreviation gap.\n\nCredit: anir0y (independent security research).",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "npm",
      "name" : "simple-git"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "4.0.0"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 3.36.0"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/steveukx/git-js/security/advisories/GHSA-858h-whjf-mvg5"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-102827"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/steveukx/git-js/pull/1193"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/steveukx/git-js/commit/98864c678444d9336357c844efa4fd5a7984c0d7"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/steveukx/git-js"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/steveukx/git-js/releases/tag/simple-git@4.0.0"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-77", "CWE-88" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-10-05T23:47:58Z",
    "nvd_published_at" : "2026-09-29T19:17:25Z"
  }
}