GitHub Advisoryadvisory · PyPI
GHSA-3wxw-xv34-2frg GitPython: TagReference.create positional reference bypasses kwargs-only --file guard, enabling arbitrary file read (incomplete fix of 3af0c251)
MEDIUM
Official page ↗
- Aliases
- CVE-2026-78679
- Ecosystem
- PyPI
- Packages
- GitPython
- Severity
- Moderate
- CVSS vector
- CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
- Weaknesses
- CWE-200, CWE-88
- Reviewed
- 2026-09-08
Affected packages
• PyPI GitPython: < 3.1.59 → fixed in 3.1.59
Description
Summary
`TagReference.create()` forwards a caller-influenced positional `reference` value into `git tag` without it ever being inspected by the unsafe-option guard, allowing an arbitrary file read (the file's contents are returned in-band as the annotated tag message). This is an incomplete-fix bypass of commit `3af0c251` (the fix for GHSA-3f7w-8rr8-f37f's tag instance).
Root Cause
The fix `3af0c251` added `unsafe_git_tag_options = ["--file","-F"]` and a guard call, but the guard is `Git.check_unsafe_options(options=Git._option_candidates([], kwargs), unsafe_options=...)` at `git/refs/tag.py:139` — it passes an EMPTY args list and inspects kwargs only. The dangerous values `path` and `reference` are POSITIONALS (`args = (path, reference)`, tag.py:156), placed before any `--`. A user-influenced `reference="--file="` therefore reaches `git tag` as the exact `--file` option the fix intended to block, creating an annotated tag whose message is the file's contents.
Impact
Arbitrary local file read at the privileges of the host process; contents returned in-band via `tagref.tag.message`. Requires the embedding application to forward a caller-influenced `reference` value into `TagReference.create()` (pure VALUE control — the CVE-2026-42215 threat model). Default `allow_unsafe_options=False`.
Proof of Concept
```python
from git import TagReference
t = TagReference.create(repo, "vpwn", reference="--file=/home/app/.ssh/id_rsa")
print(t.tag.message) # contents of the file
```
Attack Chain
1. Entry: app calls `TagReference.create(repo, name, reference=)` with `reference="--file=/home/app/.ssh/id_rsa"`.
2. Check: `Git.check_unsafe_options(_option_candidates([], kwargs), ["--file","-F"])` @ tag.py:137-141. Guard: denylist includes `--file`/`-F`. Bypass proof: `_option_candidates` receives `args=[]` → the positional `reference` is never a candidate (the kwarg spelling `file="…"` IS blocked; only the positional escapes).
3. Sink: `repo.git.tag(*args, kwargs)` @ tag.py:158 → no `--`. argv (observed): `['git','tag','-f','vpwn','--file=']`.
4. Impact: annotated tag created; `tagref.tag.message` == file contents (arbitrary file read).
Bypass Evidence
Independently reproduced (independent test harness, git 2.43.0, default `allow_unsafe_options=False`): `TagReference.create(repo,'vp','--file=')` → PASSED; `tag.message == 'GATE_SECRET_LINE_A\nGATE_SECRET_LINE_B'`. Control: `TagReference.create(..., file='')` → `UnsafeOptionError: --file is not allowed`. Fix-commit read: `3af0c251` adds `_option_candidates([], kwargs)` (empty args → positional never a candidate).
Affected Versions
`GitPython <= 3.1.58` (sink present verbatim on the latest release tag; `git diff 3.1.57..HEAD` touches only test files).
Suggested Fix
Include the positional `reference` (and `path`) in the option-candidate list passed to `check_unsafe_options`, or place a `--` separator before the positional arguments in `TagReference.create()`.
---
Reported by zx (Jace)** — GitHub: @manus-use
Related
Alias · CVE (1)
- CVE-2026-78679 GitPython before 3.1.59 contains an arbitrary file read vulnerability in TagReference.create() where a positional reference parameter… vulnerability
References
- https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-3wxw-xv34-2frg web
- https://nvd.nist.gov/vuln/detail/CVE-2026-78679 advisory
- https://github.com/gitpython-developers/GitPython/pull/2208 web
- https://github.com/gitpython-developers/GitPython/commit/1b0d2d9b91575f7db44ef4ff58ac37fc9335e5f6 web
- https://github.com/gitpython-developers/GitPython package
- https://github.com/gitpython-developers/GitPython/releases/tag/3.1.59 web
- https://www.vulncheck.com/advisories/gitpython-before-arbitrary-file-read-via-tagreference-create web