CVE-2024-22190 Overview
CVE-2024-22190 is an untrusted search path vulnerability [CWE-426] in GitPython, a Python library used to interact with Git repositories. The flaw represents an incomplete fix for CVE-2023-40590. On Windows, GitPython uses an untrusted search path when it invokes a shell to run git, or when it runs bash.exe to interpret hooks. An attacker who plants a malicious git.exe or bash.exe in a repository can achieve code execution when a victim uses GitPython to operate on that repository. The issue is patched in GitPython version 3.1.41.
Critical Impact
A malicious binary placed in an untrusted repository can execute in the context of the user running GitPython on Windows, leading to full local compromise.
Affected Products
- GitPython versions prior to 3.1.41 on Windows
- Applications using GitPython with shell=True for git invocation
- Applications using GitPython to execute Git hooks via bash.exe
Discovery Timeline
- 2024-01-11 - CVE-2024-22190 published to NVD
- 2026-06-17 - Last updated in NVD database
Technical Details for CVE-2024-22190
Vulnerability Analysis
The vulnerability stems from Windows-specific process creation behavior. When Python's subprocess.Popen runs an executable on Windows without an absolute path, the search order includes the current working directory before directories on PATH. GitPython invokes git through the shell in certain code paths and spawns bash.exe to interpret hooks, both of which are subject to this search order. An attacker who commits a git.exe or bash.exe binary to the root of a repository can cause that binary to run instead of the system-installed executable.
The original fix for CVE-2023-40590 addressed direct invocations of git.exe but did not cover shell-mediated invocations or the hook interpreter path. This left the same class of hijack exploitable through alternative code paths.
Root Cause
The root cause is the use of an untrusted executable search path [CWE-426] on Windows. GitPython relied on default Popen semantics that resolve executables against the current working directory. Because repositories can contain arbitrary files, an attacker-controlled repository can supply the resolved binary.
Attack Vector
Exploitation requires local access and user interaction. A victim must clone or otherwise operate against a malicious repository using a GitPython-based application on Windows. When the application invokes git via shell or runs a Git hook, the attacker-planted git.exe or bash.exe executes with the victim's privileges.
# Security patch in git/index/fun.py (from PR #1792)
# Replaces direct Popen usage with a safer wrapper that avoids
# resolving executables against the current working directory.
import subprocess
-from git.cmd import PROC_CREATIONFLAGS, handle_process_output
+from git.cmd import handle_process_output, safer_popen
from git.compat import defenc, force_bytes, force_text, safe_decode
from git.exc import HookExecutionError, UnmergedEntriesError
from git.objects.fun import (
Source: GitHub Commit ef3192cc
The patch introduces a safer_popen helper and clarifies the behavior of py_where:
# Security patch in git/util.py (from PR #1792)
def py_where(program: str, path: Optional[PathLike] = None) -> List[str]:
+ """Perform a path search to assist :func:`is_cygwin_git`.
+
+ This is not robust for general use. It is an implementation detail of
+ :func:`is_cygwin_git`. When a search following all shell rules is needed,
+ :func:`shutil.which` can be used instead.
+
+ :note: Neither this function nor :func:`shutil.which` will predict the effect of an
+ executable search on a native Windows system due to a :class:`subprocess.Popen`
+ call without ``shell=True``, because shell and non-shell executable search on
+ Windows differ considerably.
+ """
# From: http://stackoverflow.com/a/377028/548792
winprog_exts = _get_exe_extensions()
Source: GitHub Commit ef3192cc
Detection Methods for CVE-2024-22190
Indicators of Compromise
- Presence of git.exe or bash.exe files at the root of a cloned Git repository.
- Unexpected child processes spawned from Python interpreters running GitPython on Windows hosts.
- Process creation events where git.exe or bash.exe executes from a user-writable working directory rather than Program Files or System32.
Detection Strategies
- Inventory Python environments to identify installations of gitpython older than 3.1.41 using pip list or equivalent tooling.
- Monitor endpoint process telemetry for git.exe or bash.exe executions whose image path resolves to a repository or user-download directory.
- Alert when a Python process spawns a shell that in turn executes git.exe from a non-standard location.
Monitoring Recommendations
- Correlate Git clone operations with subsequent executions of git.exe and bash.exe from within the cloned directory tree.
- Track command-line arguments and parent-child process relationships for CI/CD runners and developer workstations that use GitPython.
- Baseline the expected install path of git.exe on managed Windows hosts and alert on deviations.
How to Mitigate CVE-2024-22190
Immediate Actions Required
- Upgrade GitPython to version 3.1.41 or later on all Windows systems.
- Audit applications and CI/CD pipelines for GitPython usage that clones or operates on untrusted repositories.
- Instruct developers not to clone untrusted repositories into working directories that will be operated on by GitPython-based tooling on Windows.
Patch Information
The fix is available in GitPython 3.1.41, delivered through Pull Request #1792 and commit ef3192cc. Full technical details are in the GitHub Security Advisory GHSA-2mqj-m65w-jghx. The patch introduces a safer_popen wrapper that avoids resolving executables against the current working directory.
Workarounds
- Avoid running GitPython code paths that use shell=True on Windows against untrusted repositories.
- Disable execution of Git hooks when processing untrusted repositories, since hook execution triggers the bash.exe search path issue.
- Run GitPython-based tooling from a directory that does not contain untrusted repository contents and ensure git.exe is invoked by absolute path where possible.
# Upgrade GitPython to the patched release
pip install --upgrade "gitpython>=3.1.41"
# Verify installed version
python -c "import git; print(git.__version__)"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

