Apr 27, 2026·7 min read·54 visits
GitPython < 3.1.45 fails to properly filter dangerous Git options when supplied via Python keyword arguments. Attackers can bypass security checks by using underscores instead of hyphens (e.g., `upload_pack` instead of `upload-pack`), resulting in arbitrary remote code execution via the underlying Git executable.
GitPython versions prior to 3.1.45 are vulnerable to a command injection flaw due to an architectural logic error in how keyword arguments are sanitized. The library attempts to block dangerous Git options like `--upload-pack` but performs this validation before applying Pythonic underscore-to-hyphen normalization. This allows attackers to bypass the blocklist using underscore-formatted arguments, leading to arbitrary command execution when the underlying Git binary is invoked.
GitPython is a Python library used to interact with Git repositories, providing an object-oriented wrapper around the underlying Git command-line interface. Developers frequently use this library to programmatically clone, fetch, pull, and manipulate repositories. The vulnerability, identified as GHSA-RPM5-65CW-6HJ4, exists within the parameter processing pipeline where Python keyword arguments are translated into Git command-line options.
To bridge Python conventions and POSIX command-line flags, GitPython allows developers to pass keyword arguments (kwargs) using underscores, which the library automatically normalizes into hyphens. For example, passing upload_pack='...' in Python translates to --upload-pack='...' at the command line. This normalization is a core feature designed to maintain Python code readability while adhering to Git's expected argument syntax.
GitPython maintains a security blocklist to prevent the injection of dangerous Git options that natively support command execution, such as --upload-pack, --receive-pack, and --extcmd. The vulnerability occurs because the library executes this security validation step before performing the underscore-to-hyphen normalization. Consequently, an attacker can supply the dangerous arguments in their pre-normalized underscore form to bypass the security filter entirely.
Once the validation step completes successfully, GitPython normalizes the malicious keyword argument and passes the hyphenated flag to the Git subprocess. This results in the execution of arbitrary operating system commands with the privileges of the Python process invoking the Git wrapper.
The root cause of GHSA-RPM5-65CW-6HJ4 is an architectural sequencing error in the input sanitization pipeline. Effective input validation mandates that data must be normalized to its final, canonical representation before any security checks are applied. GitPython violates this principle by evaluating the input in its raw form rather than its normalized execution form.
When a developer invokes a Git command via the GitPython API, the library packages the provided keyword arguments into a dictionary. The security function iterates over the keys in this dictionary, checking against a hardcoded list of restricted strings. The blocklist specifically contains the standard Git command-line formats, specifically upload-pack, receive-pack, and extcmd.
If the dictionary key is provided as upload_pack, the string comparison against the blocklist fails, and the security check permits the argument. Following this validation, the library's command builder processes the dictionary to construct the actual shell command string. During this phase, it replaces all underscores in the dictionary keys with hyphens to match Git's parameter requirements.
The normalized dictionary keys are then concatenated with their respective values and appended to the Git binary path. The resulting command array is passed to Python's subprocess execution module. By processing the validation phase prematurely, GitPython guarantees that the command builder will subsequently mutate the validated input into an unsafe state, completely nullifying the intended security controls.
Understanding the vulnerability requires analyzing the exact data flow of the keyword arguments. The flaw exists in the method responsible for transforming the **kwargs dictionary into the final list of arguments passed to the subprocess.Popen call.
The implementation flaw is evident in the execution order. The Python dictionary {'upload_pack': 'touch /tmp/pwned'} is passed to the validation routine. The routine checks for the literal string upload-pack. Since upload_pack (with an underscore) does not match upload-pack (with a hyphen), no exception is raised.
After the validation loop completes, a separate processing loop handles the command string assembly. This loop takes upload_pack, runs a string replace operation for underscores, and yields --upload-pack. It then appends the provided value, resulting in --upload-pack=touch /tmp/pwned.
The patch for this vulnerability involves shifting the validation logic to occur after the normalization step, or explicitly checking both the underscore and hyphenated variations of the dangerous parameters. By normalizing the dictionary keys to their canonical hyphenated state first, the security check correctly identifies the prohibited arguments regardless of how they were initially formatted in the Python code.
Exploitation of this vulnerability requires the application using GitPython to accept user-controlled input and apply it as a keyword argument to a Git command execution function. This pattern is increasingly common in automated CI/CD pipelines, repository management tools, and "agentic" AI systems that dynamically generate operational commands based on user prompts.
An attacker crafts a malicious payload targeting a remote Git operation, such as clone, fetch, pull, or push. The payload specifies the upload_pack argument, utilizing the underscore format to ensure the application processes it without triggering the built-in GitPython exception. The value of this argument contains the actual operating system commands the attacker wishes to execute.
import git
# The attacker controls this input variable via a web form or API endpoint
dangerous_option = "touch /tmp/pwned"
repo = git.Repo.init("/tmp/test-repo")
# The developer passes the user input as a keyword argument
# The underscore bypasses the GitPython security blocklist
repo.git.fetch(upload_pack=dangerous_option)When the vulnerable application processes this code, GitPython constructs and executes the command git fetch --upload-pack='touch /tmp/pwned'. The git fetch operation natively supports the --upload-pack parameter to specify the path to the git-upload-pack binary on the remote end. However, Git executes the provided string as a shell command to initialize the pack transfer, resulting in immediate arbitrary code execution on the local host processing the fetch request.
The vulnerability enables arbitrary OS command execution, representing a critical risk to systems utilizing vulnerable versions of GitPython. The injected commands execute with the identical permissions and environment variables of the Python application hosting the GitPython library.
In environments where GitPython operates as part of a backend web service or API, successful exploitation yields a full remote shell or direct access to the underlying filesystem. Attackers can leverage this foothold to exfiltrate sensitive data, manipulate internal databases, or extract environment variables containing secondary authentication tokens, such as AWS credentials or database passwords.
This vulnerability is particularly consequential for AI-driven development tools and automated repository management systems. These platforms frequently parse user instructions or arbitrary repository data and map them into dynamically constructed Git commands. If these inputs dictate the keyword arguments passed to the GitPython wrapper, the system is immediately vulnerable to complete compromise without requiring authentication bypasses in the primary web application.
The definitive remediation for this vulnerability is upgrading GitPython to version 3.1.45 or later. The patched release restructures the validation logic to accurately identify and block dangerous Git options, even when they are supplied using Python's underscore-based keyword argument syntax. Organizations should update dependencies via pip, poetry, or their respective package managers immediately.
If upgrading is not operationally feasible in the short term, developers must implement strict input validation at the application layer. Before passing any dynamic dictionary or user-controlled input to GitPython via **kwargs, the application must manually inspect all keys. Any keys matching upload_pack, receive_pack, extcmd, or their hyphenated equivalents must be explicitly rejected.
Furthermore, developers should adopt a strict allowlist approach when mapping untrusted data to system command interfaces. Avoid dynamically expanding untrusted dictionaries directly into function calls. Instead, map specific, expected user inputs to hardcoded arguments within the application logic, ensuring that arbitrary Git options cannot be introduced into the command pipeline regardless of library-level validation failures.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
GitPython gitpython-developers | < 3.1.45 | 3.1.45 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-78: Improper Neutralization of Special Elements used in an OS Command |
| Attack Vector | Network / Context Dependent |
| Impact | Remote Code Execution (RCE) |
| CVSS Score | 8.8 (Estimated) |
| Exploit Status | Proof of Concept Available |
| Vulnerable Component | Git command wrappers (`repo.git.*`) |
The software constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component.
An uncontrolled resource consumption vulnerability exists in the Scala-based http4s-blaze-server package of the http4s/blaze library. The vulnerability allows remote, unauthenticated attackers to cause an Out of Memory Error (OOM) and JVM crash by streaming a continuous sequence of small or empty WebSocket continuation frames with the FIN bit set to 0. This bypasses typical payload size checks because of the JVM's per-object allocation overhead, leading to rapid heap exhaustion with minimal network bandwidth.
A critical path traversal vulnerability has been identified in the OpenList Go-based backend package. The vulnerability exists within the batch rename handler because the application does not validate the source filename parameter before constructing filesystems paths. This omission allows authenticated users to escape their designated directory and rename files in sibling paths.
OpenList version 4.2.3 and prior is vulnerable to an authorization bypass and metadata leakage. When configured with the Bleve search engine backend, OpenList fails to perform separator-aware path matching when validating tenant containment. This allows authenticated users to access sibling directories sharing similar name prefixes. Furthermore, the search backend returns unfiltered global result counts, leaking existence verification data of unauthorized files via side-channel analysis.
An authorization bypass vulnerability in OpenList version 4.2.3 and below allows authenticated users to read arbitrary files outside of their designated base directories due to an insecure path prefix check using Go's standard strings.HasPrefix function.
A security policy bypass vulnerability exists in the AWS API MCP Server (awslabs-aws-api-mcp-server) from version 0.2.13 through 1.3.46. When the server fails to load the read-only operations index during startup (due to transient network failures, file permission issues, or other exceptions), it logs a warning but continues running in an insecure, degraded state. Under this condition, the security policy engine fails open, silently skipping all subsequent security checks and consent prompts for the lifetime of the process. This permits unauthorized mutating AWS CLI commands to execute via indirect prompt injection attacks.
An incomplete escaping vulnerability in the npm package 'shescape' allows unauthenticated users to trigger dynamic shell expansions, absolute path disclosure, and command block break-outs on Unix and Windows systems.