CVE-2026-110859
GitPython before 3.2.0 Arbitrary File Read via Head.checkout() Branch Name
GitPython before 3.2.0 contains an argument injection vulnerability in Head.checkout() that allows remote attackers to read arbitrary files by supplying a branch name parsed as a git option. Attackers can host a repository whose default branch is named --pathspec-from-file=<path>, causing cloning applications that check out the active branch to leak file contents through GitCommandError messages.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
8.7
GitPython before 3.2.0 Arbitrary File Read via Head.checkout() Branch Name
GitPython before 3.2.0 contains an argument injection vulnerability in Head.checkout() that allows remote attackers to read arbitrary files by supplying a branch name parsed as a git option. Attackers can host a repository whose default branch is named --pathspec-from-file=<path>, causing cloning applications that check out the active branch to leak file contents through GitCommandError messages.
- Record
CVE-2026-110859- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-88
- Updated
- 2026-11-02
EUVDEUVD-2026-101742
8.7
GitPython before 3.2.0 contains an argument injection vulnerability in Head.checkout() that allows remote attackers to read arbitrary files by supplying a branch name parsed as a git option. Attackers can host a repository whose default branch is named --pathspec-from-file=<path>, causing cloning applications that check out the active branch to leak file contents through GitCommandError messages.
- Record
EUVD-2026-101742- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-23mf-xhv8-69c2
7.1
GitPython: arbitrary file read via attacker-controlled branch name in `Head.checkout()` (incomplete fix of CVE-2026-78679)
A note on the referenced files. This report was submitted through GitHub's private vulnerability reporting API, which carries no attachments. Every transcript this report leans on is reproduced inline above, verbatim. The file names it mentions (
poc.sh,poc.log, per-case transcripts,evidence.md,negative-controls.md, blob-sweep tables) are the local evidence bundle those inline excerpts were extracted from, with a checksum manifest. I am happy to send the bundle by any channel you prefer, or to open a private fork — just say which. The PoC scripts are self-contained and reproduce the result from a clean environment.
Affected: <= 3.1.62 — all published releases; also main @ 4905b4af
Verified at runtime: GitPython 3.1.62 with git 2.55.0
Date: 2026-09-10
Reporter: MAXI8594
Threat model
| | |
|---|---|
| Attacker | anyone who can get the application to clone a URL they control. No account, no credential, no privilege in the consuming application. |
| Pre-need | a repository they host, with HEAD pointing at a branch whose name is the payload. A git push to a plain git server is enough — no filesystem access to a server is required (raw/06). |
| Gets | the contents of any file the application's process can read, returned in band through the exception. /etc/passwd recovered 34 of 34 lines. |
| Real-world likelihood | High. The vulnerable consumer is six lines of ordinary code with no unusual configuration: Repo.clone_from(user_url) then repo.active_branch.checkout(). allow_unsafe_options=False is the default. Cloning user-supplied URLs is the library's central use case — CI systems, repository importers, scanners and bots. |
On severity relative to the sibling advisories. GitHub, as CNA, scored the three prior
advisories in this class at 6.5 / PR:L (CVE-2026-76217, CVE-2026-78678, CVE-2026-78679). This
report asks for 7.5 / PR:N, and the difference is one measured fact: in those three, the
application had to pass an attacker-influenced value into the API. Here it passes nothing — the
clone materialises the hostile branch on its own and repo.active_branch returns it
(raw/02). If that reading is not accepted, the PR:L path via Repo.create_head() is also real
and lands at 6.5, matching the siblings.
Summary
Head.checkout() guards its **kwargs against unsafe Git options but never inspects its own
positional argument — the branch name — which reaches the git checkout argv with no --
separator. A repository whose default branch is named --pathspec-from-file=/etc/passwd makes a
consumer that merely clones it and checks out the default branch return the entire contents of that
file to the caller.
This is the exact combination of two advisories the project already fixed:
- CVE-2026-76217 (
GHSA-hh9p-6wh2-4mfc) — "Arbitrary file read via--pathspec-from-fileinIndexFile.remove()andHead.checkout()". Fixed in 3.1.58 by commitf2550b65, which added the guard to this exact method — but only for**kwargs. - CVE-2026-78679 (
GHSA-3wxw-xv34-2frg) — "TagReference.createpositional reference bypasses kwargs-only--fileguard, enabling arbitrary file read (incomplete fix of 3af0c251)". Fixed in 3.1.59 by commit1b0d2d9b, which applied the positional check togit/refs/tag.py,git/diff.py,git/index/base.pyandgit/repo/base.py— but not togit/refs/head.py:286.
f2550b65 states in its own commit message that the audit found the positional variant and applied
it to HEAD.reset — 185 lines above Head.checkout, in the same file, in the same commit:
"The audit also found that reset's positional commit could carry the option before its argument separator. […] Check reset's positional commit as well as keyword options"
HEAD.reset got the fix. Head.checkout did not, and 1b0d2d9b did not come back for it.
##…
- Record
GHSA-23mf-xhv8-69c2- CVSS 4.0
- 7.1 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-73, CWE-88, CWE-200
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-pv89-gqgv-pcc9
8.7
GitPython before 3.2.0 contains an argument injection vulnerability in Head.checkout() that...
GitPython before 3.2.0 contains an argument injection vulnerability in Head.checkout() that allows remote attackers to read arbitrary files by supplying a branch name parsed as a git option. Attackers can host a repository whose default branch is named --pathspec-from-file=<path>, causing cloning applications that check out the active branch to leak file contents through GitCommandError messages.
- Record
GHSA-pv89-gqgv-pcc9- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-88
- Updated
- 2026-11-02
NVD
8.7
GitPython before 3.2.0 contains an argument injection vulnerability in Head.checkout() that allows remote attackers to read arbitrary files by supplying a branch name parsed as a git option. Attackers can host a repository whose default branch is named --pathspec-from-file=<path>, causing cloning applications that check out the active branch to leak file contents through GitCommandError messages.
- Record
CVE-2026-110859- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-88
- Updated
- 2026-11-02
OSV
8.7
GitPython before 3.2.0 Arbitrary File Read via Head.checkout() Branch Name
GitPython before 3.2.0 contains an argument injection vulnerability in Head.checkout() that allows remote attackers to read arbitrary files by supplying a branch name parsed as a git option. Attackers can host a repository whose default branch is named --pathspec-from-file=<path>, causing cloning applications that check out the active branch to leak file contents through GitCommandError messages.
- Record
CVE-2026-110859- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-88
- Updated
- 2026-11-03
Show 6 moreShow less
OSVDEBIAN-CVE-2026-110859
8.7
GitPython before 3.2.0 contains an argument injection vulnerability in Head.checkout() that allows remote attackers to read arbitrary files by supplying a branch name parsed as a git option. Attackers can host a repository whose default branch is named --pathspec-from-file=<path>, causing cloning applications that check out the active branch to leak file contents through GitCommandError messages.
- Record
DEBIAN-CVE-2026-110859- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Updated
- 2026-11-02
OSVGHSA-23mf-xhv8-69c2
7.1
GitPython: arbitrary file read via attacker-controlled branch name in `Head.checkout()` (incomplete fix of CVE-2026-78679)
A note on the referenced files. This report was submitted through GitHub's private vulnerability reporting API, which carries no attachments. Every transcript this report leans on is reproduced inline above, verbatim. The file names it mentions (
poc.sh,poc.log, per-case transcripts,evidence.md,negative-controls.md, blob-sweep tables) are the local evidence bundle those inline excerpts were extracted from, with a checksum manifest. I am happy to send the bundle by any channel you prefer, or to open a private fork — just say which. The PoC scripts are self-contained and reproduce the result from a clean environment.
Affected: <= 3.1.62 — all published releases; also main @ 4905b4af
Verified at runtime: GitPython 3.1.62 with git 2.55.0
Date: 2026-09-10
Reporter: MAXI8594
Threat model
| | |
|---|---|
| Attacker | anyone who can get the application to clone a URL they control. No account, no credential, no privilege in the consuming application. |
| Pre-need | a repository they host, with HEAD pointing at a branch whose name is the payload. A git push to a plain git server is enough — no filesystem access to a server is required (raw/06). |
| Gets | the contents of any file the application's process can read, returned in band through the exception. /etc/passwd recovered 34 of 34 lines. |
| Real-world likelihood | High. The vulnerable consumer is six lines of ordinary code with no unusual configuration: Repo.clone_from(user_url) then repo.active_branch.checkout(). allow_unsafe_options=False is the default. Cloning user-supplied URLs is the library's central use case — CI systems, repository importers, scanners and bots. |
On severity relative to the sibling advisories. GitHub, as CNA, scored the three prior
advisories in this class at 6.5 / PR:L (CVE-2026-76217, CVE-2026-78678, CVE-2026-78679). This
report asks for 7.5 / PR:N, and the difference is one measured fact: in those three, the
application had to pass an attacker-influenced value into the API. Here it passes nothing — the
clone materialises the hostile branch on its own and repo.active_branch returns it
(raw/02). If that reading is not accepted, the PR:L path via Repo.create_head() is also real
and lands at 6.5, matching the siblings.
Summary
Head.checkout() guards its **kwargs against unsafe Git options but never inspects its own
positional argument — the branch name — which reaches the git checkout argv with no --
separator. A repository whose default branch is named --pathspec-from-file=/etc/passwd makes a
consumer that merely clones it and checks out the default branch return the entire contents of that
file to the caller.
This is the exact combination of two advisories the project already fixed:
- CVE-2026-76217 (
GHSA-hh9p-6wh2-4mfc) — "Arbitrary file read via--pathspec-from-fileinIndexFile.remove()andHead.checkout()". Fixed in 3.1.58 by commitf2550b65, which added the guard to this exact method — but only for**kwargs. - CVE-2026-78679 (
GHSA-3wxw-xv34-2frg) — "TagReference.createpositional reference bypasses kwargs-only--fileguard, enabling arbitrary file read (incomplete fix of 3af0c251)". Fixed in 3.1.59 by commit1b0d2d9b, which applied the positional check togit/refs/tag.py,git/diff.py,git/index/base.pyandgit/repo/base.py— but not togit/refs/head.py:286.
f2550b65 states in its own commit message that the audit found the positional variant and applied
it to HEAD.reset — 185 lines above Head.checkout, in the same file, in the same commit:
"The audit also found that reset's positional commit could carry the option before its argument separator. […] Check reset's positional commit as well as keyword options"
HEAD.reset got the fix. Head.checkout did not, and 1b0d2d9b did not come back for it.
##…
- Record
GHSA-23mf-xhv8-69c2- CVSS 4.0
- 7.1 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-200, CWE-73, CWE-88
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-110859
8.7
GitPython before 3.2.0 contains an argument injection vulnerability in Head.checkout() that allows remote attackers to read arbitrary files by supplying a branch name parsed as a git option. Attackers can host a repository whose default branch is named --pathspec-from-file=<path>, causing cloning applications that check out the active branch to leak file contents through GitCommandError messages.
- Record
UBUNTU-CVE-2026-110859- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Updated
- 2026-11-02
OSVCLSA-2026-1792479054 No score
TuxCare security update for gitpython (7 CVEs)
TuxCare rebuilt gitpython to address 7 CVEs. Fixed in 3.1.31.post15+tuxcare.
- Record
CLSA-2026-1792479054- Updated
- 2026-11-02
OSVMGASA-2026-0580 No score
Updated python-gitpython package fixes security vulnerabilities
Please see the links for additional information.
- Record
MGASA-2026-0580- Updated
- 2026-11-07
OSVopenSUSE-SU-2026:12391-1 No score
python313-GitPython-3.2.1-1.1 on GA media
These are all security issues fixed in the python313-GitPython-3.2.1-1.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2026:12391-1- Updated
- 2026-11-03
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
gitpythonPyPI |
through 3.1.62 | 3.2.0 |
gitpythonTuxCare:PyPI From an advisory covering 4 CVEs |
3.1.31 up to 3.1.31.post15+tuxcare, plus listed versions 3.1.31.post1+tuxcare3.1.31.post10+tuxcare3.1.31.post11+tuxcare3.1.31.post12+tuxcare3.1.31.post13+tuxcare Show 9 moreShow less3.1.31.post14+tuxcare3.1.31.post2+tuxcare3.1.31.post3+tuxcare3.1.31.post4+tuxcare3.1.31.post5+tuxcare3.1.31.post6+tuxcare3.1.31.post7+tuxcare3.1.31.post8+tuxcare3.1.31.post9+tuxcare |
3.1.31.post15+tuxcare |
python-gitDebian:12 |
before 3.1.30-1+deb12u3, plus listed versions 3.1.30-13.1.30-1+deb12u2 |
3.1.30-1+deb12u3 |
python-gitDebian:14 |
before 3.2.1-1, plus listed versions 3.1.44-13.1.45-13.1.46-13.1.50-13.1.61-13.1.62-13.1.62-23.1.62-3 |
3.2.1-1 |
gitpythonPyPI |
before 3.2.0, plus listed versions 0.1.70.2.0-beta10.3.0-beta10.3.0-beta20.3.1-beta2 Show 45 moreShow less0.3.20.3.2.10.3.2.RC10.3.30.3.40.3.50.3.60.3.71.0.01.0.11.0.22.0.02.0.12.0.22.0.32.0.42.0.52.0.62.0.72.0.82.0.92.0.9.dev02.0.9.dev12.1.02.1.12.1.102.1.112.1.122.1.132.1.142.1.152.1.22.1.32.1.42.1.52.1.62.1.72.1.82.1.93.0.03.0.13.0.23.0.33.0.43.0.5 |
3.2.0 |
python-gitpythonMageia:10 From an advisory covering 6 CVEs |
before 3.2.1-1.mga10 | 3.2.1-1.mga10 |
python-gitUbuntu:Pro:14.04:LTS |
All versions, plus listed versions 0.3.2~RC1-20.3.2~RC1-30.3.2~RC1-3ubuntu0.1~esm10.3.2~RC1-3ubuntu0.1~esm20.3.2~RC1-3ubuntu0.1~esm3 |
None known |
python-gitUbuntu:Pro:16.04:LTS |
All versions, plus listed versions 1.0.1+git137-gc8b8379-11.0.1+git137-gc8b8379-21.0.1+git137-gc8b8379-2.11.0.1+git137-gc8b8379-2.1ubuntu0.1~esm11.0.1+git137-gc8b8379-2.1ubuntu0.1~esm21.0.1+git137-gc8b8379-2.1ubuntu0.1~esm4 |
None known |
python-gitUbuntu:Pro:18.04:LTS |
All versions, plus listed versions 2.1.5-12.1.6-12.1.7-12.1.8-12.1.8-1ubuntu0.1~esm12.1.8-1ubuntu0.1~esm22.1.8-1ubuntu0.1~esm4 |
None known |
python-gitUbuntu:Pro:20.04:LTS |
All versions, plus listed versions 2.1.11-13.0.4-13.0.5-13.0.7-13.0.7-1ubuntu0.1~esm13.0.7-1ubuntu0.1~esm23.0.7-1ubuntu0.1~esm4 |
None known |
Show 5 moreShow less
| Package | Affected | Fixed |
|---|---|---|
python-gitUbuntu:Pro:22.04:LTS |
All versions, plus listed versions 3.1.14-13.1.23-13.1.24-13.1.24-1ubuntu0.1~esm13.1.24-1ubuntu0.1~esm23.1.24-1ubuntu0.1~esm3 |
None known |
python-gitUbuntu:Pro:24.04:LTS |
All versions, plus listed versions 3.1.30-13.1.37-13.1.37-33.1.37-3ubuntu0.1~esm2 |
None known |
python-gitUbuntu:26.10 |
All versions, plus listed versions 3.1.46-13.1.50-13.1.61-1 |
None known |
python-gitUbuntu:Pro:26.04:LTS |
All versions, plus listed versions 3.1.44-13.1.45-13.1.46-13.1.46-1ubuntu0.1~esm1 |
None known |
python-GitPythonopenSUSE:Tumbleweed From an advisory covering 6 CVEs |
before 3.2.1-1.1 | 3.2.1-1.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, aliases, references | OSV | |
| affected | ||
| affected, aliases, facts, references | OSV | |
| affected, aliases | ||
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-110859 is a high vulnerability (CVSS 8.7) in Gitpython-developers Gitpython, published October 14, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.39%, the 32nd percentile. Fixed in gitpython 3.2.0.
References
github.com/gitpython-developers/GitPython/security/advisories/GHSA-23mf-xhv8-69c2
vulncheck.com/advisories/gitpython-before-3.2.0-arbitrary-file-read-via-head-checkout-branch-name
github.com/gitpython-developers/GitPython/pull/2233
github.com/gitpython-developers/GitPython/commit/8da65080849a56a2fc9f3e7817bbf0524e8397d5
github.com/gitpython-developers/GitPython/releases/tag/3.2.0
github.com/advisories/GHSA-23mf-xhv8-69c2
Show 17 moreShow less
nvd.nist.gov/vuln/detail/CVE-2026-110859
github.com/advisories/GHSA-pv89-gqgv-pcc9
github.com/CVEProject/cvelistV5/tree/main/cves/2026/110xxx/CVE-2026-110859.json
security-tracker.debian.org/tracker/CVE-2026-110859
github.com/gitpython-developers/GitPython
advisories.mageia.org/MGASA-2026-0580.html
bugs.mageia.org/show_bug.cgi?id=36507
github.com/gitpython-developers/GitPython/releases
lists.fedoraproject.org/archives/list/[email protected]/message/OOS5EDMLYZWKECAUWB5INCTGXLGARLNL
ubuntu.com/security/CVE-2026-110859
cve.org/CVERecord?id=CVE-2026-110859
suse.com/security/cve/CVE-2026-110855
suse.com/security/cve/CVE-2026-110856
suse.com/security/cve/CVE-2026-110857
suse.com/security/cve/CVE-2026-110858
suse.com/security/cve/CVE-2026-110859
suse.com/security/cve/CVE-2026-114145
Left out here: 65 versions and the rest of 2 source descriptions. The JSON record has them.