GHSA-4gmw-gg2m-w46p: High severity pip/GitPython vulnerability
Summary IndexFile.fromtree, IndexFile.reset (→ fromtree) and IndexFile.mergetree append caller-influenced treeish strings positionally to git read-tree with no unsafe-option guard, no allowunsafeoptions parameter, and no -- separator. git read-tree --index-output=<file> writes the resulting index to an arbitrary path, and last-occurrence-wins lets an injected --index-output override the method's internal temp path — clobbering an arbitrary file with a valid git-index blob. This is a distinct, never-guarded sink: commit 3af0c251 (GHSA-3f7w-8rr8-f37f) guarded only checkoutindex and tag; readtree was left unprotected (it is among the acknowledged unguarded call sites in that advisory's sweep but was never reported or fixed).
Root Cause fromtree (index/base.py:388), reset (delegates to fromtree), and mergetree (index/base.py:291) call repo.git.readtree(arglist) with no checkunsafeoptions and no --. The treeish is caller-influenced and positional.
Impact Arbitrary file overwrite / destruction at the privileges of the host process. Content is constrained to a git-index blob (not attacker-chosen, so not RCE), but the target path is fully attacker-controlled — corrupting/truncating configs or destroying files at attacker-chosen writable locations = I:H + A:H (per the skill's "overwrite-any-path = I:H" rule). Pure VALUE control (positional treeish). Default configuration.
Proof of Concept python IndexFile.fromtree(repo, "--index-output=/home/victim/.bashrc") target overwritten with a valid git-index blob (DIRC...)
Attack Chain 1. Entry: app calls IndexFile.fromtree(repo, treeish) / reset(commit=…) / mergetree(base=…, rhs=…) with attacker treeish="--index-output=/home/victim/.bashrc". 2. Check: NONE — the methods have no allowunsafeoptions and never call checkunsafeoptions. 3. Sink: repo.git.readtree(arglist) — no --. argv (fromtree, observed): ['git','read-tree','--index-output=<tmp>','--index-output=/…/victim'] (last-wins). 4. Impact: target path created/overwritten with a valid git-index blob; existing content destroyed.
Bypass Evidence Independently reproduced (gate harness): IndexFile.fromtree(repo,'--index-output=<victim>') → victim overwritten; before=IMPORTANT ORIGINAL CONTENT, after starts DIRC\x00\x00\x00\x02… (destructive clobber, valid index blob). reset(commit=…) and both mergetree positionals verified. Fix-commit read: 3af0c251 touched only checkoutindex+tag; readtree untouched on HEAD.
Affected Versions GitPython <= 3.1.57 (sinks present verbatim on the latest release tag).
Suggested Fix Add a checkunsafeoptions guard (with an allowunsafeoptions parameter) to fromtree/reset/mergetree, and/or place a -- separator before the positional treeish arguments; block --index-output (a path-taking option) on this sink.
--- 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 - Upgrade
Upgrade to a fixed release to a version that resolves this vulnerability.
Patch GHSA-3f7w-8rr8-f37f - Configuration
In IndexFile.from_tree (index/base.py:388), IndexFile.reset (delegates to from_tree), and IndexFile.merge_tree (index/base.py:291), ensure the attacker-controlled positional treeish arguments cannot inject unsafe/path-taking options into the git read-tree call. Specifically: add a check_unsafe_options guard with an allow_unsafe_options parameter to from_tree/reset/merge_tree before calling repo.git.read_tree(*arg_list), and/or insert a `--` separator before the positional treeish arguments; additionally block `--index-output` (a path-taking option) on this sink.
GitPython IndexFile.from_tree / reset / merge_tree Unsafe option handling for positional treeish passed to git read-tree = Add check_unsafe_options guard with allow_unsafe_options parameter; do not allow path-taking options like --index-output in the sink - Compensating control
Until the code change is deployed, prevent calls from reaching a sink that accepts injected read-tree options with `--index-output`. Use external isolation controls so the host process cannot write to attacker-selected paths (e.g., restrict the process/user filesystem permissions so the target paths (like /home/victim/.bashrc or any writable config locations) are not writable by the host process).
Event History
Frequently Asked Questions
What is the severity of GHSA-4gmw-gg2m-w46p?
The severity of GHSA-4gmw-gg2m-w46p is high, rated at 8.1.
How do I fix GHSA-4gmw-gg2m-w46p?
To fix GHSA-4gmw-gg2m-w46p, update to the latest version of GitPython that includes the required security patches.
What are the potential risks of GHSA-4gmw-gg2m-w46p?
GHSA-4gmw-gg2m-w46p could allow unauthorized access or modifications due to improper handling of user-influenced treeish strings.
Which software is affected by GHSA-4gmw-gg2m-w46p?
GHSA-4gmw-gg2m-w46p affects the GitPython library, specifically versions prior to the patch release.
How can I identify if I'm affected by GHSA-4gmw-gg2m-w46p?
You can identify if you are affected by GHSA-4gmw-gg2m-w46p by checking if you are using an affected version of GitPython prior to the patch.