π DefectDojo Finding
| Field |
Value |
| Severity |
High |
| Product |
Latch/connectedhomeip |
| Finding ID |
#14667 |
| CVE |
GHSA-4gmw-gg2m-w46p |
| Component |
GitPython |
| File |
scripts/requirements.txt |
π Description
Summary
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).
Root Cause
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.
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
IndexFile.from_tree(repo, "--index-output=/home/victim/.bashrc")
# target overwritten with a valid git-index blob (DIRC...)
Attack Chain
- Entry: app calls
IndexFile.from_tree(repo, treeish) / reset(commit=β¦) / merge_tree(base=β¦, rhs=β¦) with attacker treeish="--index-output=/home/victim/.bashrc".
- Check: NONE β the methods have no
allow_unsafe_options and never call check_unsafe_options.
- Sink:
repo.git.read_tree(*arg_list) β no --. argv (from_tree, observed): ['git','read-tree','--index-output=<tmp>','--index-output=/β¦/victim'] (last-wins).
- Impact: target path created/overwritten with a valid git-index blob; existing content destroyed.
Bypass Evidence
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.
Affected Versions
GitPython <= 3.1.57 (sinks present verbatim on the latest release tag).
Suggested Fix
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
π References
GHSA-4gmw-gg2m-w46p
gitpython-developers/GitPython#2204
gitpython-developers/GitPython@9b5dcaf
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.58
GHSA-4gmw-gg2m-w46p
π€ Auto-created from DefectDojo.
π DefectDojo Finding
π Description
Summary
IndexFile.from_tree,IndexFile.reset(β from_tree) andIndexFile.merge_treeappend caller-influenced treeish strings positionally togit read-treewith no unsafe-option guard, noallow_unsafe_optionsparameter, 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-outputoverride the method's internal temp path β clobbering an arbitrary file with a valid git-index blob. This is a distinct, never-guarded sink: commit3af0c251(GHSA-3f7w-8rr8-f37f) guarded onlycheckout_indexandtag;read_treewas left unprotected (it is among the acknowledged unguarded call sites in that advisory's sweep but was never reported or fixed).Root Cause
from_tree(index/base.py:388),reset(delegates to from_tree), andmerge_tree(index/base.py:291) callrepo.git.read_tree(*arg_list)with nocheck_unsafe_optionsand 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
Attack Chain
IndexFile.from_tree(repo, treeish)/reset(commit=β¦)/merge_tree(base=β¦, rhs=β¦)with attackertreeish="--index-output=/home/victim/.bashrc".allow_unsafe_optionsand never callcheck_unsafe_options.repo.git.read_tree(*arg_list)β no--. argv (from_tree, observed):['git','read-tree','--index-output=<tmp>','--index-output=/β¦/victim'](last-wins).Bypass Evidence
Independently reproduced (gate harness):
IndexFile.from_tree(repo,'--index-output=<victim>')β victim overwritten; before=IMPORTANT ORIGINAL CONTENT, after startsDIRC\x00\x00\x00\x02β¦(destructive clobber, valid index blob).reset(commit=β¦)and bothmerge_treepositionals verified. Fix-commit read:3af0c251touched onlycheckout_index+tag;read_treeuntouched on HEAD.Affected Versions
GitPython <= 3.1.57(sinks present verbatim on the latest release tag).Suggested Fix
Add a
check_unsafe_optionsguard (with anallow_unsafe_optionsparameter) tofrom_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
π References
GHSA-4gmw-gg2m-w46p
gitpython-developers/GitPython#2204
gitpython-developers/GitPython@9b5dcaf
https://github.com/gitpython-developers/GitPython/releases/tag/3.1.58
GHSA-4gmw-gg2m-w46p