GHSA-858H-WHJF-MVG5
Vulnerability from github – Published: 2026-10-05 23:47 – Updated: 2026-10-05 23:47simple-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 (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).
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.36.0"
},
"package": {
"ecosystem": "npm",
"name": "simple-git"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.0.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-102827"
],
"database_specific": {
"cwe_ids": [
"CWE-77",
"CWE-88"
],
"github_reviewed": true,
"github_reviewed_at": "2026-10-05T23:47:58Z",
"nvd_published_at": "2026-09-29T19:17:25Z",
"severity": "HIGH"
},
"details": "simple-git\u0027s 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 \u0027-pack\u0027) and the string \u0027--exec\u0027. 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=\u003ccmd\u003e` parses with flag.name=\u0027--receive-p\u0027, which /--(upload|receive)-pack/ does NOT match, yet git expands --receive-p -\u003e --receive-pack and runs \u003ccmd\u003e (on a local/file remote, locally). The clone side is robust (its \u0027--u\u0027 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: \u0027push --receive-pack=touch...\u0027 -\u003e BLOCKED; \u0027push --receive-pa=touch...\u0027 and \u0027push --receive-p=touch...\u0027 -\u003e BYPASS (empty vulns); \u0027--exec=\u0027 BLOCKED, \u0027--exe=\u0027 BYPASS.\nEnd-to-end via simpleGit().push():\n CONTROL git.push([\u0027../bare\u0027,\u0027HEAD:refs/heads/c\u0027,\u0027--receive-pack=touch /tmp/pwned_ctrl;\u0027]) -\u003e throws GitPluginError \u0027Use of --upload-pack or --receive-pack is not permitted...\u0027; no command runs.\n BYPASS git.push([\u0027../bare\u0027,\u0027HEAD:refs/heads/e2e\u0027,\u0027--receive-p=touch /tmp/pwned_e2e;\u0027]) -\u003e NO GitPluginError; /tmp/pwned_e2e CREATED (git executed the injected command); only a later GitError surfaces.\nDirect git confirms `git push ../bare --receive-p=\u0027touch X;\u0027 HEAD:refs/heads/m` and `--exe=\u0027touch Y;\u0027` both execute on a local/path remote.\n\nImpact: any app relying on simple-git\u0027s 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 \u0027--u\u0027 approach). Also audit --template and -c/config-write detection for the same abbreviation gap.\n\nCredit: anir0y (independent security research).",
"id": "GHSA-858h-whjf-mvg5",
"modified": "2026-10-05T23:47:58Z",
"published": "2026-10-05T23:47:58Z",
"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"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "simple-git: unsafe-operations plugin bypass via git long-option abbreviation (--receive-p/--exe) -\u003e command execution (residual of CVE-2026-28291)"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.