GitPython flaw lets hostile repos run code on clone
An advisory published on 30 September 2026 says GitPython 3.1.59 can mistake attacker-controlled files for the git directory, then execute a tracked hook.
By The Agentic Times ·

A GitHub Security Advisory published on 30 September 2026 describes an arbitrary code execution flaw in GitPython, the Python library used to drive git from code. The advisory, tracked as GHSA-239g-whfq-7xj9 and CVE-2026-87817, says version 3.1.59 can be tricked into treating the root of a cloned working tree as the git directory, so ordinary files committed by an attacker are then trusted and, in the case of hooks, run.
According to the advisory, the cause is the order in which Repo.__init__ searches for the git directory. The discovery loop first checks whether the candidate path contains files named gitdir, commondir and HEAD, then calls is_git_dir on the path, and only considers the real .git directory last. Git reserves only the literal name .git, so files and folders called HEAD, objects/, refs/, config, gitdir, commondir and hooks/ are all legal tracked content at a repository root. The advisory notes that is_git_dir never parses the contents of HEAD; it only requires that objects/ and refs/ are directories and HEAD is a file.
The published proof of concept needs four tracked files at the repository root: gitdir and commondir containing .git, a HEAD file, and an executable hooks/pre-commit script. On the victim side, two normal calls are enough — cloning or opening the repository, then calling index.commit(). The advisory says the pre-commit hook runs before the tree is written, so the payload fires even though the commit later fails. The behaviour was observed on the PyPI release 3.1.59 on both Linux and Windows.
Code execution is not the only impact listed. Because the tracked config file becomes the repository config and is parsed with include merging enabled, an attacker can use an include directive to disclose a file outside the repository, such as cloud credentials in a user's home directory. An absolute path in a tracked commondir can also cause a config file to be written to a directory of the attacker's choosing.
The advisory stresses that delivery is quiet. A clone exits successfully, git fsck reports nothing even in strict mode, and read-only checks such as listing branches or iterating commits all behave normally, because the tracked commondir pins the common directory to the real .git. Setting GIT_WORK_TREE is not a mitigation, the advisory says, because the git directory is assigned before the environment is consulted. Real git itself is unaffected.
The listed victims are any service that opens or clones an untrusted repository with GitPython: continuous integration runners building fork pull requests, code-scanning and SBOM services, mirrors, dependency bots and AI code-review or agent tools.
The advisory recommends testing curpath/.git before the other checks, resolving hook paths through the repository's common directory, containment-checking commondir and gitdir values, validating the contents of HEAD, and disabling include merging in the config reader. It also records that a commit from 31 May 2026 resolved hook paths through git rev-parse --git-path and was immune, but was reverted on 20 July 2026 to avoid the dependency, reintroducing the execution step.
Sources
- github.comhttps://github.com/advisories/GHSA-239g-whfq-7xj9
