GitPython: submodule path validated after clone lets attacker plant executable git hooks (CVE-2026-114145)
Severity: high · Patch status: patched · Since 2026-10-14 · CVE-2026-114145
GitPython's Submodule.add() validates a submodule checkout path only after cloning into it, breaking the validate-before-mutation invariant. A path like '.git/hooks' passes the pre-clone check, so an attacker-influenced submodule is cloned directly into the repo's live hooks directory, planting an attacker-controlled executable post-checkout hook. On 3.2.0+ a ValueError is raised at index time but the planted hook is not removed; on 3.1.x the call succeeds silently. Either way, the next git checkout executes the hook, giving arbitrary code execution. Exploitation requires an app to pass an attacker-influenced submodule path and an empty hooks directory (common in CI/container checkouts). A public PoC exists; no in-the-wild exploitation is known. Fixed in GitPython 3.2.1.
What to do
- Upgrade GitPython to 3.2.1 or later wherever the library is used, especially in services that create submodules from user-supplied manifests or API input
- As a mitigation, never pass attacker-controlled paths to create_submodule; reject any path starting with '.git' or containing '..' before calling the library
- Audit systems for planted hooks: check .git/hooks directories for unexpected executable files such as post-checkout, particularly on CI runners and containers
- If a suspicious hook is found, remove it, investigate what executed it, and rotate any credentials accessible from those environments
- Ensure git hook template directories are populated or hooks directories are non-writable where submodule creation from untrusted input cannot be ruled out
Fixed versions
Sources
All live incidents on Threat Watch