Oct 1, 2026·5 min read·5 visits
GitPython versions up to 3.1.61 do not validate submodule update paths, allowing recursive checkouts to execute directory traversals and write files outside repository boundaries.
A path traversal vulnerability exists in GitPython when handling submodule updates recursively. If an attacker crafts a malicious repository with traversed paths or symbolic links in the submodule configuration, they can execute arbitrary file writes outside the parent repository's working directory. This can lead to system configuration modifications or arbitrary code execution.
GitPython is a popular Python library designed to interact with Git repositories by wrapping system Git command-line calls or implementing native functions.
The vulnerability tracked as GHSA-59CR-6R3X-644W is a technical flaw in the library's submodule handling mechanism. If an application uses GitPython to clone and recursively update an untrusted repository, an attacker can manipulate the submodule path structure to perform out-of-bounds file writes.
This behavior bypasses standard workspace containment barriers and can be leveraged to write files directly to critical folders on the host operating system. The flaw affects all versions of GitPython up to and including 3.1.61, and has been addressed in version 3.1.62.
In Git repositories, submodules are defined within the .gitmodules file, which maps local subdirectory paths to remote repository URLs. During a submodule update command such as repo.submodule_update(), GitPython resolves the destination filesystem path utilizing the abspath property of the Submodule class.
Prior to the patch in version 3.1.62, the abspath property resolved paths directly from the raw path attribute defined in the .gitmodules configuration or the repository index. This attribute was not checked against the parent repository's working tree boundary before initialization or update operations.
This lack of verification allows two primary traversal vectors. First, directory traversal sequences like ../ are evaluated literally, pointing target destinations outside the repository root. Second, if a checked-in symbolic link exists in the workspace, the submodule path resolution follows the symlink to external directories, causing subsequent git clone operations to write files directly to targeted system paths.
The vulnerability was fixed in commit 1ed0ebc2f2e74d979cdc367a4864a7731fdcc093 by overriding the abspath property in git/objects/submodule/base.py to enforce strict containment checks.
Below is the patched code structure implementing the path containment check:
@property
def abspath(self) -> PathLike:
root = self.repo.working_tree_dir
if root is None:
return super().abspath
path = root
for component in os.fspath(self._to_relative_path(self.repo, self.path)).split("/"):
path = join_path_native(path, component)
if osp.islink(path):
raise ValueError("Submodule checkout path %r contains a symbolic link" % self.path)
return pathThe implementation first retrieves the absolute parent repository working directory root. It then normalizes the submodule path via self._to_relative_path(self.repo, self.path), raising a ValueError if the path escapes the repository directory.
To prevent symlink traversal attacks, the method splits the normalized path into individual directory components. It validates each step of the resolved path with osp.islink(path). If any directory component along the path resolution is a symbolic link, the check immediately raises a ValueError to prevent arbitrary file writes.
An attack requires the victim to perform a recursive submodule update on an untrusted or attacker-controlled repository. An attacker constructs a repository with a .gitmodules file pointing to a hostile submodule containing a traversal path or a symbolic link pointing to a sensitive system folder.
The following Mermaid diagram outlines the path traversal attack flow during a recursive submodule update operation:
When submodule.update(init=True) is called in a vulnerable environment, GitPython invokes subprocesses that clone and write the submodule's repository structure directly into the target traversed or symlinked folder. No authentication is required other than the willingness of the user or automated pipeline to process the repository.
Successful exploitation of this vulnerability allows arbitrary file writes on the filesystem hosting the GitPython process. The exact impact depends on the execution environment and the privileges of the running application.
In environments where GitPython runs as a privileged user or within an automated continuous integration pipeline, this flaw can lead to remote code execution. An attacker can write malicious configurations, inject scripts into startup folders, or overwrite standard shell files like .bashrc or authorized SSH key lists.
The vulnerability is tracked under the GitHub Security Advisory GHSA-59CR-6R3X-644W. It does not have an assigned CVE identifier, which means automated scanners relying solely on standard CVE databases will fail to flag this issue.
The primary remediation path is upgrading the GitPython dependency to version 3.1.62 or later. This version enforces path normalization and symlink checks during submodule path resolution, raising errors before any external clone or write occurs.
If immediate upgrade is not feasible, organizations should implement strict workarounds. Applications must avoid running recursive submodule updates on untrusted, user-provided repositories. Running GitPython within sandboxed container environments with minimal write permissions to the parent host filesystem is highly recommended.
Additionally, static analysis can be utilized to scan incoming .gitmodules files and repository layouts for directory traversal sequences or symbolic links before invoking GitPython submodule APIs.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
GitPython gitpython-developers | <= 3.1.61 | 3.1.62 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-22, CWE-59 |
| Attack Vector | Local/Remote via User Interaction |
| CVSS Score | 8.8 |
| Impact | Arbitrary File Write / Code Execution |
| Exploit Status | Proof of Concept (PoC) |
| CISA KEV Status | Not Listed |
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
An improper neutralization of input during web page generation (CWE-79) vulnerability exists in the server-side rendering JSX engine (hono/jsx) of the Hono web framework prior to version 4.13.7. The flaw enables unauthenticated remote attackers to execute arbitrary JavaScript in the victim's browser context by supplying unescaped HTML characters into user-controlled fields rendered within specific boundary components, context providers, or direct server-side utilities.
A path traversal and arbitrary file disclosure vulnerability exists in Tornado's StaticFileHandler. In versions prior to 6.5.9, the handler follows symbolic links that point outside of the configured root static directory. This behavior occurs because the handler performs lexical path validation rather than physical filesystem resolution, allowing unauthenticated remote attackers to read arbitrary files if they can access or control symbolic links within the served static root.
A critical uncontrolled resource consumption vulnerability exists in the Tornado web server's libcurl-based HTTP client (CurlAsyncHTTPClient). When processing highly compressed responses with response decompression enabled, the client experiences unbounded memory growth. This leads to host memory exhaustion and denial of service via application crashes.
An uncontrolled resource consumption vulnerability in Tornado's HTTP query-string parser allows remote, unauthenticated attackers to trigger CPU exhaustion and block the single-threaded event loop via crafted request URIs containing large numbers of parameters.
PyJWT versions 2.11.0 through 2.13.0 suffer from a state pollution vulnerability in the `_merge_options` method. When an application passes a mutable configuration mapping with signature verification disabled, the library modifies the object in-place. If this same dictionary is reused for subsequent verified decode operations, standard claim verifications (such as expiration, audience, and issuer validation) are silently bypassed.
A protocol validation vulnerability exists in Fastify before version 5.12.5. When serving requests over HTTP/2, Fastify unconditionally injects the forbidden Transfer-Encoding header when response trailers are used, triggering an uncaught exception in Node.js and crashing the process.