Command Injection
Description
The package simple-git before 3.5.0 are vulnerable to Command Injection due to an incomplete fix of CVE-2022-24433 which only patches against the git fetch attack vector. A similar use of the --upload-pack feature of git is also supported for git clone, which the prior fix didn't cover.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
simple-git before 3.5.0 is vulnerable to command injection via the --upload-pack argument in git clone, bypassing a prior fix for git fetch.
Vulnerability
The package simple-git before version 3.5.0 is vulnerable to command injection due to an incomplete fix for CVE-2022-24433 [2]. The prior fix only blocked the --upload-pack argument in git fetch, but the same feature is also supported in git clone, allowing an attacker to inject arbitrary commands [2]. The vulnerability exists in the clone method of simple-git [4].
Exploitation
An attacker can exploit this by providing a malicious --upload-pack argument to the git clone command via simple-git. This can be done by passing the argument as part of the remote or branch parameter, as a varargs object, or as an array [4]. The attacker does not require authentication if the application accepts user-controlled input for clone parameters [2].
Impact
Successful exploitation allows an attacker to execute arbitrary commands on the host system with the privileges of the Node.js process running simple-git [2]. This can lead to full system compromise, data exfiltration, or further lateral movement.
Mitigation
The vulnerability is fixed in simple-git version 3.5.0 [3]. Users should upgrade to this version or later. The fix blocks the --upload-pack argument in git clone by checking for potential exploit arguments [4]. No workaround is available for earlier versions.
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
simple-gitnpm | < 3.5.0 | 3.5.0 |
Affected products
2- simple-git/simple-gitdescription
Patches
12040de601c89Prevent use of `--upload-pack` as a command in `git.clone` to avoid potential accidental command execution.
3 files changed · +51 −16
.changeset/wicked-files-vanish.md+5 −0 added@@ -0,0 +1,5 @@ +--- +"simple-git": minor +--- + +Resolves potential command injection vulnerability by preventing use of `--upload-pack` in `git.clone`
simple-git/src/lib/tasks/clone.ts+18 −14 modified@@ -1,10 +1,9 @@ -import { straightThroughStringTask } from './task'; +import { configurationErrorTask, EmptyTask, straightThroughStringTask } from './task'; import { OptionFlags, Options, StringTask } from '../types'; -import { append } from '../utils'; +import { append, filterString } from '../utils'; export type CloneOptions = Options & - OptionFlags< - '--bare' | + OptionFlags<'--bare' | '--dissociate' | '--mirror' | '--no-checkout' | @@ -15,25 +14,30 @@ export type CloneOptions = Options & '--remote-submodules' | '--single-branch' | '--shallow-submodules' | - '--verbose' - > & + '--verbose'> & OptionFlags<'--depth' | '-j' | '--jobs', number> & OptionFlags<'--branch' | '--origin' | '--recurse-submodules' | '--separate-git-dir' | '--shallow-exclude' | '--shallow-since' | '--template', string> -export function cloneTask(repo: string | undefined, directory: string | undefined, customArgs: string[]): StringTask<string> { +function disallowedCommand(command: string) { + return /^--upload-pack(=|$)/.test(command); +} + +export function cloneTask(repo: string | undefined, directory: string | undefined, customArgs: string[]): StringTask<string> | EmptyTask { const commands = ['clone', ...customArgs]; - if (typeof repo === 'string') { - commands.push(repo); - } - if (typeof directory === 'string') { - commands.push(directory); + + filterString(repo) && commands.push(repo); + filterString(directory) && commands.push(directory); + + const banned = commands.find(disallowedCommand); + if (banned) { + return configurationErrorTask(`git.fetch: potential exploit argument blocked.`); } return straightThroughStringTask(commands); } -export function cloneMirrorTask(repo: string | undefined, directory: string | undefined, customArgs: string[]): StringTask<string> { - append(customArgs,'--mirror'); +export function cloneMirrorTask(repo: string | undefined, directory: string | undefined, customArgs: string[]) { + append(customArgs, '--mirror'); return cloneTask(repo, directory, customArgs); }
simple-git/test/unit/clone.spec.ts+28 −2 modified@@ -1,5 +1,6 @@ +import { promiseError } from '@kwsites/promise-result'; import { SimpleGit, TaskOptions } from 'typings'; -import { assertExecutedCommands, closeWithSuccess, newSimpleGit } from './__fixtures__'; +import { assertExecutedCommands, assertGitError, closeWithSuccess, newSimpleGit } from './__fixtures__'; describe('clone', () => { let git: SimpleGit; @@ -15,7 +16,7 @@ describe('clone', () => { beforeEach(() => git = newSimpleGit()); - it.each(cloneTests)('callbacks - %s %s', async (api, name, cloneArgs, executedCommands)=> { + it.each(cloneTests)('callbacks - %s %s', async (api, name, cloneArgs, executedCommands) => { const callback = jest.fn(); const queue = (git[api] as any)(...cloneArgs, callback); await closeWithSuccess(name); @@ -32,5 +33,30 @@ describe('clone', () => { expect(await queue).toBe(name); assertExecutedCommands(...executedCommands); }); + + describe('failures', () => { + + it('disallows upload-pack as remote/branch', async () => { + const error = await promiseError(git.clone('origin', '--upload-pack=touch ./foo')); + + assertGitError(error, 'potential exploit argument blocked'); + }); + + it('disallows upload-pack as varargs', async () => { + const error = await promiseError(git.clone('origin', 'main', { + '--upload-pack': 'touch ./foo' + })); + + assertGitError(error, 'potential exploit argument blocked'); + }); + + it('disallows upload-pack as varargs', async () => { + const error = await promiseError(git.clone('origin', 'main', [ + '--upload-pack', 'touch ./foo' + ])); + + assertGitError(error, 'potential exploit argument blocked'); + }); + }); });
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-28xr-mwxg-3qc8ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-24066ghsaADVISORY
- gist.github.com/lirantal/a930d902294b833514e821102316426bghsax_refsource_MISCWEB
- github.com/steveukx/git-js/commit/2040de601c894363050fef9f28af367b169a56c5ghsax_refsource_MISCWEB
- github.com/steveukx/git-js/releases/tag/simple-git%403.5.0ghsaWEB
- snyk.io/vuln/SNYK-JAVA-ORGWEBJARSNPM-2434820ghsax_refsource_MISCWEB
- snyk.io/vuln/SNYK-JS-SIMPLEGIT-2434306ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.