Every CVE Search/ Get API key

CVE-2026-110859

GitPython before 3.2.0 Arbitrary File Read via Head.checkout() Branch Name

8.7 HighFix available

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

0.39%Up 0.1 points since Oct 15, 2026
90%50%10%1%

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 HighCVSS: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 HighCVSS: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 HighCVSS: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-file in IndexFile.remove() and Head.checkout()". Fixed in 3.1.58 by commit f2550b65, which added the guard to this exact method — but only for **kwargs.
  • CVE-2026-78679 (GHSA-3wxw-xv34-2frg) — "TagReference.create positional reference bypasses kwargs-only --file guard, enabling arbitrary file read (incomplete fix of 3af0c251)". Fixed in 3.1.59 by commit 1b0d2d9b, which applied the positional check to git/refs/tag.py, git/diff.py, git/index/base.py and git/repo/base.py — but not to git/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 HighCVSS: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 HighCVSS: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 HighCVSS: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 HighCVSS: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 HighCVSS: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 HighCVSS: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 HighCVSS: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-file in IndexFile.remove() and Head.checkout()". Fixed in 3.1.58 by commit f2550b65, which added the guard to this exact method — but only for **kwargs.
  • CVE-2026-78679 (GHSA-3wxw-xv34-2frg) — "TagReference.create positional reference bypasses kwargs-only --file guard, enabling arbitrary file read (incomplete fix of 3af0c251)". Fixed in 3.1.59 by commit 1b0d2d9b, which applied the positional check to git/refs/tag.py, git/diff.py, git/index/base.py and git/repo/base.py — but not to git/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 HighCVSS: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 HighCVSS: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 HighCVSS: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

Affected packages
PackageAffectedFixed
gitpython
PyPI
through 3.1.62
3.2.0
gitpython
TuxCare: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 less
3.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-git
Debian:12
before 3.1.30-1+deb12u3, plus listed versions
3.1.30-13.1.30-1+deb12u2
3.1.30-1+deb12u3
python-git
Debian: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
gitpython
PyPI
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 less
0.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-gitpython
Mageia:10
From an advisory covering 6 CVEs
before 3.2.1-1.mga10
3.2.1-1.mga10
python-git
Ubuntu: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-git
Ubuntu: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-git
Ubuntu: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-git
Ubuntu: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
Affected packages
PackageAffectedFixed
python-git
Ubuntu: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-git
Ubuntu: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-git
Ubuntu:26.10
All versions, plus listed versions
3.1.46-13.1.50-13.1.61-1
None known
python-git
Ubuntu: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-GitPython
openSUSE:Tumbleweed
From an advisory covering 6 CVEs
before 3.2.1-1.1
3.2.1-1.1

History

History
RecordedChangedSources
affected, aliases, referencesOSV
affected
affected, aliases, facts, referencesOSV
affected, aliases
first indexedCVE 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

Show 17 moreShow less
This page doesn't list everything

Left out here: 65 versions and the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open