CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-2F96-G7MH-G2HX

GHSA-2F96-G7MH-G2HX: Command Injection Bypass in GitPython Options Validation

Amit Schendel
Amit Schendel
Senior Security Researcher

Jul 21, 2026·5 min read·59 visits

Executive Summary (TL;DR)

GitPython fails to validate abbreviated long options and clustered short options, allowing attackers to bypass the unsafe option filters and execute arbitrary shell commands.

GitPython prior to version 3.1.51 contains a command injection vulnerability due to flaws in its option validation routine. By exploiting Git's native argument parser behavior, specifically long-option abbreviation resolution and short-option clustering, attackers can bypass the check_unsafe_options blocklist to execute arbitrary OS commands.

Vulnerability Overview

GitPython is a Python library used to interact with Git repositories. Applications rely on its API to clone repositories, fetch commits, and manage git configurations. The library includes a defensive security component named check_unsafe_options designed to prevent remote command execution by validating command line options passed to git processes.

This security boundary is designed to block dangerous parameters such as --upload-pack and -u which can run arbitrary code on the underlying host. However, a major architectural limitation in how GitPython validates these parameters allows attackers to construct payloads that evade validation while resolving into executable payloads inside Git's native CLI wrapper.

The vulnerability is classified as CWE-78 (OS Command Injection) and CWE-184 (Incomplete Blacklist / Blocklist). It affects all deployments of GitPython prior to version 3.1.51 where untrusted inputs are passed to repository subcommand parameters.

Root Cause Analysis

The root cause of this vulnerability lies in the logical mismatch between GitPython's exact-match validation logic and Git's native command-line option parser implemented in parse-options.c.

First, Git permits long-option prefix abbreviations. If an option starting with a specific prefix is unique among all valid option names for a given subcommand, Git automatically resolves that prefix to the full option name. For example, Git automatically interprets --upload-p as --upload-pack because there are no other options starting with --upload-p for that command.

Second, Git natively supports short-option clustering and direct value attachment. This feature allows multiple single-dash flags to be combined in a single block (e.g., -fq instead of -f -q) and allows parameters to be directly attached to their target value without spaces or equal signs (e.g., -u/bin/sh).

GitPython's original check_unsafe_options implementation validated options by performing exact-match lookups against a static blocklist of dangerous strings. Because the blocklist only checked for literal strings like --upload-pack or -u, it was completely bypassed by options leveraging abbreviation (like --upload-p) or value attachment (like -utouch). When these bypassed arguments reached the Git process, the Git engine successfully expanded and executed them.

Code Analysis

The original verification logic in GitPython parsed argument inputs without evaluating character boundaries or abbreviation paths.

# Vulnerable implementation in git/cmd.py (Simplified)
canonical_unsafe_options = {cls._canonicalize_option_name(option): option for option in unsafe_options}
for option in options:
    candidate = cls._canonicalize_option_name(option)
    # Exact-match validation failed to detect abbreviations or joined option strings
    unsafe_option = canonical_unsafe_options.get(candidate)
    if unsafe_option is not None:
        raise UnsafeOptionError(f"{unsafe_option} is not allowed...")

In the patched version (3.1.51), the developer added character-by-character analysis of short-option tokens and checked for long-option abbreviation paths:

# Patched implementation in git/cmd.py
canonical_unsafe_options = {cls._canonicalize_option_name(option): option for option in unsafe_options}
 
# Extract unsafe single-character options (e.g., 'u', 'c')
unsafe_short_options = {
    canonical: option
    for canonical, option in canonical_unsafe_options.items()
    if option.startswith("-") and not option.startswith("--") and len(canonical) == 1
}
 
clusterable_short_options = frozenset("46flnqsv")
for option in options:
    candidate = cls._canonicalize_option_name(option)
    
    # Manual scanning of short-option characters and clustered values
    option_token = option.split("=", 1)[0].split(None, 1)[0]
    if option_token.startswith("-") and not option_token.startswith("--"):
        for option_char in option_token[1:]:
            unsafe_option = unsafe_short_options.get(option_char)
            if unsafe_option is not None:
                raise UnsafeOptionError(
                    f"{unsafe_option} is not allowed, use `allow_unsafe_options=True` to allow it."
                )
            # Terminate scan early if a non-clusterable option is hit
            if option_char not in clusterable_short_options:
                break

Exploitation and Secondary Weakness

An attacker can exploit this vulnerability by submitting repository action parameters that leverage abbreviations to subcommands handled by GitPython.

# Exploitation using prefix abbreviations on vulnerable versions (< 3.1.51)
import git
repo = git.Repo("/tmp/repo")
# By using 'upload_p', the exact match validation is bypassed
repo.git.fetch("origin", upload_p="touch /tmp/rce_poc")

Furthermore, critical evaluation of the patch reveals a secondary bypass vulnerability (CWE-184). The hardcoded set of safely clusterable flags clusterable_short_options = frozenset("46flnqsv") is incomplete.

Several subcommands contain valueless boolean flags not declared in this set. For instance, in git fetch, -p (prune) and -k (keep) are valueless boolean flags. An attacker can construct a payload such as -pu/path/to/payload. Because the parser encounters p (which is not in clusterable_short_options), it breaks execution scanning early, bypassing the checks while Git translates -pu as a combination of -p and -u, invoking the command.

Impact Assessment

Successful exploitation of this vulnerability results in arbitrary shell command execution with the privileges of the running Python application. In standard web applications running background workers or ingestion services, this allows attackers to execute commands directly on internal servers.

An attacker could retrieve environment variables containing API tokens, read sensitive files, modify repository branches, or move laterally into the internal network. The estimated CVSS score of 8.8 reflects the severity of unauthenticated remote execution contexts where user inputs are automatically processed.

Organizations running pipelines, automation platforms, or platform-as-a-service providers that accept user-provided Git repositories or parameters are at high risk.

Remediation and Defensive Guidance

The direct remediation path is upgrading GitPython dependencies to version 3.1.51 or higher, which introduces advanced scanning and token validation logic to catch option abbreviations and clustered parameters.

If patching is not immediately viable, developers must implement strict validation on all options passed to repository commands. Avoid allowing users to pass arbitrary argument variables or keyword arguments directly to low-level wrappers.

Sanitize and validate arguments using structured whitelists, allowing only expected values (such as branch names and remote URLs) and rejecting any inputs containing dashes or special symbols.

Official Patches

GitPython DevelopersSecurity Hardening Pull Request #2161
GitPython DevelopersOfficial 3.1.51 release tag containing the option-validation patch

Fix Analysis (1)

Technical Appendix

CVSS Score
8.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

Affected Systems

GitPython

Affected Versions Detail

Product
Affected Versions
Fixed Version
GitPython
gitpython-developers
< 3.1.513.1.51
AttributeDetail
CWE IDCWE-78, CWE-184
Attack VectorNetwork (Remote)
CVSS v3.1 Score8.8
Exploit Statuspoc
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1203Exploitation for Client Execution
Execution
T1190Exploit Public-Facing Application
Initial Access
CWE-184
Improper Neutralization of Input Commonly Facilitated by an Incomplete List of Disallowed Inputs ('Incomplete Blacklist')

The application fails to correctly neutralize or validate inputs that are subsequently passed as command options to an OS shell execution command, allowing for option injection bypasses.

Known Exploits & Detection

GitHubGHSA security advisory documenting the GitPython command injection bypass with code walk-throughs.

Vulnerability Timeline

Pull Request #2161 opened to address security option-validation bypasses
2026-02-12
Commit 56806080c1348749b07daa4a2024ce47b3cad285 pushed to git/cmd.py
2026-02-12
GitPython Release 3.1.51 published
2026-02-12

References & Sources

  • [1]GHSA-2F96-G7MH-G2HX Advisory
  • [2]Security Fix Commit
  • [3]Security Hardening PR #2161
  • [4]GitPython v3.1.51 Release

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•2 days ago•CVE-2026-115895
8.8

CVE-2026-115895: Code Injection via Unsanitized Import Alias in Happy DOM ECMAScript Module Compiler

CVE-2026-115895 is a high-severity code injection vulnerability (CWE-94) in the happy-dom npm package prior to version 21.0.4. The vulnerability exists within the ECMAScriptModuleCompiler component, which transforms ECMAScript module syntax into executable Node.js functions when JavaScript evaluation is enabled. Due to an incomplete fix for CVE-2026-33943, the compiler failed to validate local named import aliases against legal JavaScript identifier rules. Attackers supplying crafted module imports—specifically utilizing destructuring default initializers alongside JSON module attributes—can inject arbitrary JavaScript expressions directly into the host Node.js runtime context.

Amit Schendel
Amit Schendel
8 views•10 min read
•3 days ago•CVE-2026-115883
6.0

CVE-2026-115883: Cross-Namespace Access via Dot-Delimited Labels in LangGraph Postgres and SQLite Stores

An improper input validation and authorization bypass vulnerability exists in the LangGraph storage layer affecting langgraph, langgraph-checkpoint-postgres, and langgraph-checkpoint-sqlite. Because relational store implementations serialize namespace tuples into dot-delimited strings without validating labels on read, search, delete, and batch operations, an attacker who controls a namespace label can inject periods (.) to traverse namespace boundaries and access, modify, or delete data belonging to other namespaces.

Amit Schendel
Amit Schendel
8 views•9 min read
•3 days ago•CVE-2026-115886
6.5

CVE-2026-115886: Unauthenticated Server-Side Request Forgery and Unsafe Reflection in MLflow Scorer Evaluation Endpoints

CVE-2026-115886 (GHSA-2wqp-q3c6-ccj5) is a Server-Side Request Forgery (SSRF) and Unsafe Reflection vulnerability in MLflow versions 3.12.0rc0 prior to 3.17.0. Unauthenticated REST API endpoints accept serialized third-party scorer JSON payloads that are dynamically deserialized and reflectively instantiated without sanitizing constructor keyword arguments. When optional dependencies such as trulens and trulens-providers-litellm are installed, attackers can inject egress-steering arguments into the scorer payload, forcing the MLflow server to dispatch outbound HTTP requests to arbitrary internal destinations or cloud metadata services.

Alon Barad
Alon Barad
13 views•10 min read
•3 days ago•CVE-2026-113872
7.5

CVE-2026-113872: Unauthenticated Process Crash in Express Multer via Late Busboy Stream Resumption

CVE-2026-113872 (GHSA-q7qp-rjg7-q26m) is a high-severity denial-of-service vulnerability affecting the multer multipart/form-data upload middleware for Node.js and Express in versions 2.0.0 through 2.4.0. When an endpoint is configured to accept multiple files using an asynchronous fileFilter callback, a crafted, truncated multipart HTTP request can trigger an unhandled error event on the underlying busboy stream parser after request teardown has already completed. Because all error listeners are stripped during teardown, Node.js treats the resulting error event as an uncaught exception and immediately terminates the server process.

Amit Schendel
Amit Schendel
10 views•12 min read
•3 days ago•CVE-2026-115897
2.1

CVE-2026-115897: Cross-Site Scripting via Function Body Boundary Bypass in serialize-javascript

CVE-2026-115897 (also tracked as GHSA-m5mm-p8h7-m29v and aliased as CVE-2026-115754) is a Cross-Site Scripting (XSS) vulnerability in the Yahoo serialize-javascript npm package prior to version 7.1.3. The flaw exists in the regular expression used by escapeFunctionBody() to neutralize HTML script closing tags within serialized JavaScript functions. Because function bodies are sanitized in isolation before structural formatting is applied, a function whose string representation terminates directly with the sequence '</script' bypasses the positive lookahead check. When combined with serialization formatting options that introduce whitespace delimiters and a subsequent property that supplies a closing bracket, an attacker can prematurely terminate an enclosing HTML <script> block and inject arbitrary HTML or JavaScript into the rendered document.

Amit Schendel
Amit Schendel
7 views•13 min read
•3 days ago•CVE-2026-109841
5.9

CVE-2026-109841: Subresource Integrity Verification Bypass in Node.js Undici

CVE-2026-109841 is a Subresource Integrity (SRI) verification bypass vulnerability in undici, the official HTTP/1.1 and HTTP/2 client library for Node.js that powers the global fetch() implementation. The flaw stems from improper handling of case sensitivity (CWE-178) when validating cryptographic hash algorithm tokens within SRI metadata. Because undici compared incoming algorithm identifiers against a strictly lowercase set without prior ASCII-lowercase normalization, valid uppercase or mixed-case tokens such as SHA256- or Sha384- were treated as unrecognized algorithms and discarded. Under SRI forward-compatibility rules, discarding all provided tokens results in an empty integrity list, causing undici to fail open and accept tampered HTTP response bodies without cryptographic verification.

Alon Barad
Alon Barad
17 views•9 min read