GHSA-wvpp-8hx9-p66j: High severity pip/GitPython vulnerability
Summary The checkunsafeoptions guard can be bypassed on every guarded method (clone/clonefrom, fetch/pull/push, lsremote, itercommits, blame, archive) by combining a single-character kwarg with splitsinglecharoptions=False. The guard's candidate list omits the smuggled option, but transformkwarg emits a JOINED -n<value> argv token that git parses as --upload-pack=<cmd>, yielding arbitrary command execution at the default allowunsafeoptions=False. This is an incomplete-fix bypass of commit e8d0fbf7 (the fix for GHSA-r9mr-m37c-5fr3), which only emits value-derived candidates when splitsinglecharoptions is True.
Root Cause optioncandidates derives value-token candidates only under if len(key)==1 and splitsinglecharoptions: (cmd.py:1048, added by e8d0fbf7). With splitsinglecharoptions=False, optioncandidates([], {"n":"utouch <cmd>;git-upload-pack"}) returns only ['-n'] (not on the denylist), so the guard passes. But transformkwarg('n', value, splitsinglecharoptions=False) emits the JOINED token -nutouch <cmd>;git-upload-pack (cmd.py:1631). git clusters value-less short flags then parses -u<cmd> = --upload-pack=<cmd> → command execution. The hardened guard WOULD block the joined token if it saw it — the flaw is it never receives it.
Impact Arbitrary OS command execution as the host process (via --upload-pack) at default allowunsafeoptions=False, affecting all guarded methods that forward kwargs. Precondition: the app forwards a user-controlled kwargs dict containing splitsinglecharoptions=False plus a single-char key (same user-dict-forwarding model GHSA-r9mr-m37c-5fr3 accepts).
Proof of Concept python from git import Repo Repo.clonefrom(src, dst, n="utouch /tmp/ACE;git-upload-pack", splitsinglecharoptions=False) # /tmp/ACE created -> ACE
Attack Chain 1. Entry: app forwards user kwargs to Repo.clonefrom(url, path, kwargs): {splitsinglecharoptions: False, n: 'utouch /tmp/ACE;git-upload-pack'}. 2. Check: checkunsafeoptions(optioncandidates([], kwargs), unsafegitcloneoptions). Guard: denylist includes --upload-pack/-u. Bypass proof: optioncandidates yields only ['-n'] (value token skipped because split=False); guard never sees -u. 3. Sink: transformkwarg emits joined token (cmd.py:1631). argv (observed): ['git','clone','-v','-nutouch /tmp/ACE;git-upload-pack','--','<src>','<dst>']. 4. Impact: git clusters -n + -u<cmd> → runs upload-pack command → ACE.
Bypass Evidence Independently reproduced (gate harness, default allowunsafeoptions=False): the split=False payload created the marker VH05GATEACE (ACE); the clone returned normally (guard bypassed). Control: n='--upload-pack=…' (split default True) → UnsafeOptionError: --upload-pack is not allowed. Fix-commit read: e8d0fbf7 extends candidates only under if len(key)==1 and splitsinglecharoptions: — split=False skips value emission. Also confirmed the earlier clustering-parse fix (commit 56806080) does not cover this because the guard only ever receives ['-n'].
Affected Versions GitPython <= 3.1.57 (code present verbatim on the latest release tag).
Suggested Fix Make optioncandidates emit value-derived candidates regardless of splitsinglecharoptions (i.e. also for the joined -n<value> form), OR run checkunsafeoptions over the fully-transformed argv rather than the reconstructed name-only candidate list.
--- Reported by zx (Jace) — GitHub: @manus-use
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
pip/GitPythonto a version that resolves this vulnerability.Fixed in 3.1.58
Event History
Frequently Asked Questions
What is the severity of GHSA-wvpp-8hx9-p66j?
The severity of GHSA-wvpp-8hx9-p66j is high with a score of 8.8.
How do I fix GHSA-wvpp-8hx9-p66j?
To fix GHSA-wvpp-8hx9-p66j, update to the latest version of GitPython where the vulnerability has been addressed.
What impact does GHSA-wvpp-8hx9-p66j have on my application?
GHSA-wvpp-8hx9-p66j may allow attackers to bypass the `check_unsafe_options` guard and execute arbitrary methods.
Which methods are affected by GHSA-wvpp-8hx9-p66j?
The methods affected by GHSA-wvpp-8hx9-p66j include clone, clone_from, fetch, pull, push, ls_remote, iter_commits, blame, and archive.
Is there a workaround for GHSA-wvpp-8hx9-p66j while waiting for a fix?
A temporary workaround for GHSA-wvpp-8hx9-p66j is to avoid using the vulnerable methods with single-character kwargs until an update is applied.