Aug 4, 2026·6 min read·2 visits
GitPython versions <= 3.1.56 are vulnerable to arbitrary file reads and SSRF. By omitting target flags from internal argument validation tables, applications passing user kwargs to Repo.archive() or Repo.clone() can be exploited to retrieve system files or make outbound network requests.
An argument injection vulnerability in GitPython allows remote or local attackers with control over repository archive configuration options to retrieve arbitrary local files via native git archive commands. During clone operations, a sibling missing validation vulnerability in the clone option engine allows attackers to perform Server-Side Request Forgery via the git clone bundle-uri mechanism.
GitPython provides an object-oriented API wrapping native Git command-line interface utilities. Applications embedding GitPython often delegate operations such as file archiving and repository cloning to the underlying Git command engine. When invoking functions like Repo.archive() or Repo.clone(), the library dynamically translates Python keyword arguments into official command-line parameters passed directly to the local shell executing the Git CLI process.
To restrict execution vectors that allow command injection or unauthorized filesystem access, GitPython utilizes an internal validation layer. This layer matches incoming Python arguments against hardcoded denylists of known unsafe parameters. If a parameter matches the denylist, an exception is thrown, halting command execution.
During a code audit of version 3.1.56 and earlier, security researchers identified multiple missing parameters from these safety denylists. Specifically, the utility omitted --add-file and --add-virtual-file from the archive denylist, and --bundle-uri from the clone denylist. As a result, downstream applications that allow user-influenced parameters to reach GitPython components can be forced to read local files or perform unauthorized HTTP requests.
The root cause of this vulnerability lies in a membership incompleteness flaw within GitPython's verification lists located in git/repo/base.py. The validation scheme relies on checking arguments against a strict list of strings before formatting and passing them to the sub-process wrapper.
# Pre-patched unsafe_git_archive_options definition in git/repo/base.py
unsafe_git_archive_options = [
"--exec",
"--output",
"-o",
]The native git archive tool implements arguments designed to manipulate the final structure of the generated package without altering repository indices. The --add-file=<path> argument retrieves any accessible file from the underlying operating system and inserts it into the archived bundle. Similarly, --add-virtual-file=<path:content> constructs a dynamic file structure within the archive using supplied text content. Because both parameters were absent from the validation array, GitPython accepted them as safe options.
A similar architectural gap was documented in the clone wrapper logic. Standard Git protocol controls reject insecure transport mechanisms when configured to do so. However, native Git allows an alternate content acquisition source through the --bundle-uri=<uri> flag, which downloads pre-packaged repository files from a custom web address. The unsafe_git_clone_options array omitted this flag, enabling callers to circumvent protocol restrictions and force outbound network calls.
An analysis of the fix commit 7a4f5dcb7bf3cbcbf6e438017efcdfe0bc0d36ca reveals how the library maintainers patched the gap by expanding the validation vectors inside git/repo/base.py. The diff demonstrates the explicit mapping of the unsafe arguments to the existing denylist matrices.
diff --git a/git/repo/base.py b/git/repo/base.py
index ae99ed5f9..93d17252c 100644
--- a/git/repo/base.py
+++ b/git/repo/base.py
@@ -151,6 +151,8 @@ class Repo:
"-c",
# Can install hooks that execute during clone:
"--template",
+ # Fetches from a caller-controlled URL:
+ "--bundle-uri",
]
"""Options to :manpage:`git-clone(1)` that allow arbitrary commands to be executed.
@@ -172,6 +174,10 @@ class Repo:
# Writes output to a caller-controlled filesystem path.
"--output",
"-o",
+ # Reads from a caller-controlled filesystem path:
+ "--add-file",
+ # Injects a caller-controlled path and contents:
+ "--add-virtual-file",
]The update prevents validation bypasses. When Repo.archive() parses keyword parameters, any invocation mapping to add_file or add_virtual_file triggers a membership match, raising an UnsafeOptionError. The identical control mechanism handles bundle_uri mapping inside Repo.clone(). Testing files test_clone.py and test_repo.py were also modified to programmatically enforce that these specific CLI flags trigger immediate execution halts.
Exploitation relies on an application exposing the ability to run repository packaging or repository synchronization tasks where parameters are directly influenced by remote users.
In a target application configured to let users export repositories with dynamic formats, an attacker can specify the add_file argument pointing to local credentials or configurations. The internal system processes the command, binds the target path to the generated tar or zip archive, and writes the contents to the output stream. The output stream is then read by the attacker, leaking the requested local file.
In a cloning scenario, targeting the --bundle-uri parameter allows attackers to force the application server to make an HTTP request to an internal network location, such as the cloud metadata endpoint http://169.254.169.254/latest/meta-data/. This enables Server-Side Request Forgery and internal network scanning, bypassing network boundaries established to protect localized resources.
The potential consequences of this flaw depend on the access privileges of the host process running GitPython. Because --add-file bypasses standard repository constraints, it permits reading any file system item the current process owner has read access to. This includes sensitive system parameters, service accounts, database credentials, application source code, and user data.
The inclusion of --add-virtual-file creates high integrity risks. Attackers can inject rogue binary objects or source code modifications into exported release packages. Downstream consumers downloading these archives may execute untrusted payloads, converting a localized file read into a wider supply chain compromise.
The --bundle-uri bypass compromises network boundary confidentiality. Exploiting this parameter allows bad actors to probe internal ports, interface with private internal services, or exfiltrate cloud environment credentials from local management endpoints.
The primary resolution is upgrading the GitPython package to a secure release. Version 3.1.57 addresses both missing parameter lists and adds regression tests to ensure long-term stability.
If instant package updates are not feasible, code modifications must be implemented to replace denylisting logic with strict parameter allowlisting. Applications must not forward arbitrary, unvetted dictionary payloads directly to GitPython methods. Instead, translate incoming keys to an explicit list of allowed variables.
Network administrators should implement egress filtering rules to isolate build and archival systems from internal metadata services and private subnet ranges. Restricting outbound traffic prevents exploitation attempts leveraging the --bundle-uri SSRF vector.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
GitPython gitpython-developers | <= 3.1.56 | 3.1.57 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-73 |
| Attack Vector | Network |
| CVSS v3.1 | 6.5 |
| Exploit Status | Proof of Concept |
| Impact | Arbitrary File Read, Server-Side Request Forgery |
| Remediation Status | Official Patch Available |
The software allows user input to control or influence the paths or file names used in filesystem operations.
An input validation vulnerability in the npm package `ip-address` allows unauthenticated remote attackers to bypass Server-Side Request Forgery (SSRF) protections by appending a `/0` CIDR suffix to IP address strings. This causes the library's classification helper functions to incorrectly identify internal addresses as public, external addresses, while normalization helpers resolve the address back to its internal form during network connection establishment.
An argument injection vulnerability in GitPython allows remote or local attackers to execute arbitrary file reads or arbitrary file overwrites via unsafe command option forwarding. This occurs because the wrapper methods `IndexFile.checkout()` and `TagReference.create()` fail to validate parameters before passing them to system-level git invocations.
GitPython prior to version 3.1.56 is vulnerable to argument injection in the Commit.count method. An attacker who controls keyword arguments passed to this method can inject arbitrary Git options, such as --output, leading to arbitrary file truncation on the host filesystem.
A critical SQL injection vulnerability was discovered in Sequelize when configured to use the Oracle database dialect. Due to a flawed optimization design in the SQL escaping subsystem (src/sql-string.js), strings that begin with native Oracle date functions bypass standard escaping. This allows unauthenticated remote attackers to execute arbitrary SQL commands on the target database.
CVE-2026-59881 is a protocol compliance and input validation vulnerability in the client-side WebSocket implementation of the aiohttp asynchronous HTTP client/server framework for Python. Prior to version 3.14.2, the framework's parser unexpectedly accepts and attempts to decompress frames containing the RSV1 bit, even when the permessage-deflate extension has not been negotiated during the initial WebSocket handshake. This violation of RFC 6455 allows a malicious or compromised server to bypass client configuration, forcing decompression routines that can lead to high CPU and memory consumption, resulting in a denial-of-service condition.
An asynchronous HTTP client/server framework for asyncio and Python, aiohttp prior to version 3.14.2 is vulnerable to HTTP Request Smuggling. The server-side HTTP parser immediately transitions the protocol state to 'upgraded' upon receiving a WebSocket upgrade request before consuming the accompanying request body. If the backend handler rejects the upgrade request while keeping the TCP connection alive, the unconsumed request body remains in the socket buffer and is parsed as a subsequent pipelined HTTP request. This allows an attacker to smuggle requests, bypass frontend reverse proxy controls, and perform unauthorized actions.