GHSA-4gmw-gg2m-w46pHigh· 8.1▾ TwilightGitPython: Unguarded git read-tree option forwarding in IndexFile.from_tree/reset/merge_tree enables arbitrary file overwrite
▾ Twilight zone — High severity, or a signal on a lesser flaw
impact 44.6 · likelihood 0 · exploitation 0
Need a working PoC? Pro members can cast a request and our team develops one — it lands right here.
IndexFile.from_tree, IndexFile.reset (→ from_tree) and IndexFile.merge_tree append caller-influenced treeish strings positionally to git read-tree with no unsafe-option guard, no allow_unsafe_options 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 checkout_index and tag; read_tree was left unprotected (it is among the acknowledged unguarded call sites in that advisory's sweep but was never reported or fixed).
from_tree (index/base.py:388), reset (delegates to from_tree), and merge_tree (index/base.py:291) call repo.git.read_tree(*arg_list) with no check_unsafe_options and no --. The treeish is caller-influenced and positional.
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.
IndexFile.from_tree(repo, "--index-output=/home/victim/.bashrc")
# target overwritten with a valid git-index blob (DIRC...)
IndexFile.from_tree(repo, treeish) / reset(commit=…) / merge_tree(base=…, rhs=…) with attacker treeish="--index-output=/home/victim/.bashrc".allow_unsafe_options and never call check_unsafe_options.repo.git.read_tree(*arg_list) — no --. argv (from_tree, observed): ['git','read-tree','--index-output=<tmp>','--index-output=/…/victim'] (last-wins).Independently reproduced (gate harness): IndexFile.from_tree(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 merge_tree positionals verified. Fix-commit read: 3af0c251 touched only checkout_index+tag; read_tree untouched on HEAD.
GitPython <= 3.1.57 (sinks present verbatim on the latest release tag).
Add a check_unsafe_options guard (with an allow_unsafe_options parameter) to from_tree/reset/merge_tree, 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
GitPython <= 3.1.57Upgrade to a patched release:
GitPython 3.1.58Connected by shared product, vendor, weakness, or advisory.
GHSA-9rj7-rf2p-w77rHigh· 7.5GitPython: Unguarded git option forwarding in Repo.init enables arbitrary command execution via --template clone hooks
GHSA-jm78-9fvv-mhgrHigh· 8.8GitPython: git-config OPTION-name injection via =/#/whitespace bypasses name validator, enabling forged core.sshCommand/hooksPath (RCE)
GHSA-wvpp-8hx9-p66jHigh· 8.8GitPython: Unsafe git option guard bypass via split_single_char_options=False short-option token smuggling enables command execution
GHSA-7jx3-jqcp-hhgcHigh· 8.1Duplicate Advisory: GitPython: Unguarded git read-tree option forwarding in IndexFile.from_tree/reset/merge_tree enables arbitrary file overwrite
CVE-2026-76217Medium· 6.5GitPython: Arbitrary file read via --pathspec-from-file in IndexFile.remove() and Head.checkout()
GHSA-hh9p-6wh2-4mfcMedium· 6.5GitPython: Arbitrary file read via --pathspec-from-file in IndexFile.remove() and Head.checkout()