CVE-2026-100689: GitPython before 3.1.62 Path Traversal via gitmodules path
GitPython before 3.1.62 does not validate the path field read from an untrusted .gitmodules file when updating submodules. While a prior fix (GHSA-hmq2-w58f-27jc) added Submodule.validatedname() to constrain the name field, and GitPython's own containment guard Submodule.torelativepath() is applied in add() and move(), Submodule.update() derives the absolute checkout location from the raw path value without that guard. A .gitmodules entry containing directory traversal components (e.g., path = ../../../tmp/escaped) can therefore cause directories to be created via os.makedirs() outside the repository working tree, populated from the submodule URL on the clone path, and removed via shutil.rmtree() when forceremove is used. Exploitation requires an application flow that updates submodules at a non-HEAD commit (such as a historical-commit API); the common clone-then-update flow re-derives the path from a canonical tree lookup and is not affected. The issue is fixed in GitPython 3.1.62.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
GitPythonto a version that resolves this vulnerability.Fixed in 3.1.62
Event History
Frequently Asked Questions
Which GitPython workflows are exposed to this issue?
Exposure requires an application to update submodules at a non-HEAD commit, such as through a historical-commit API. The common clone-then-update flow is not affected because it re-derives the submodule path from a canonical tree lookup.
What does an attacker need to exploit the flaw?
An attacker needs to supply or influence an untrusted .gitmodules file with a path value containing directory traversal components, and cause the application to perform a submodule update at a non-HEAD commit. No authentication is required, but user interaction is required according to the supplied severity vector.
What can happen if the vulnerable update path is reached?
GitPython can create directories outside the repository working tree and populate them from the submodule URL. If force_remove is used, it can also remove the outside directory through shutil.rmtree().
What is the remediation?
Upgrade GitPython to version 3.1.62 or later. If upgrading is not immediately possible, avoid updating submodules from untrusted repositories at non-HEAD commits and avoid using force_remove in affected flows.