
Local proof-of-concept for CVE-2026-71557 demonstrating path traversal in go-git filesystem reference storage, including exploit logic and vulnerable-vs-fixed version comparison.
This repository contains a safe local proof of concept for CVE-2026-71557, based on go-git's public advisory GHSA-qgq7-7hm3-q39j.
Before the fix, storage/filesystem used a loose-reference name as the path
.git/<reference-name> without sufficient validation. A name such as
refs/heads/../../config is normalized outside the intended reference subtree
and can overwrite .git/config.
This PoC calls the real go-git API and targets only a dummy .git/config
created under a temporary directory. It does not contact a Git server, modify
an existing repository, or execute arbitrary commands.
This project is intended only for education and authorized ethical security testing. Do not use it against systems or environments without permission.
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:L)github.com/go-git/go-git/v5 <= 5.19.1github.com/go-git/go-git/v6 <= 6.0.0-alpha.45.19.26.0.0-alpha.5dotgit reference storage in storage/filesystemstorage/memoryIn v5.19.1, DotGit.SetRef passed the reference name directly to setRef as
a file name:
fileName := r.Name().String()
return d.setRef(fileName, content, old)
The root of filesystem-backed storage is normally .git. The reference name
refs/heads/../../config normalizes to config, turning a reference update
into a write to .git/config. A malicious Git server can advertise such a
name, and traversal may remain after clone/fetch refspec mapping, allowing the
attacker-controlled name to reach this storage path.
The patched implementation validates names at filesystem storage entry points,
including SetRef, Ref, and RemoveRef, and rejects names that can escape
the reference storage.
The included go.mod pins vulnerable go-git v5.19.1.
go run .
Expected key output:
[*] go-git version: v5.19.1
[*] crafted reference: refs/heads/../../config
[*] SetReference error: <nil>
[!] VULNERABLE: .git/config was overwritten through the reference name.
The PoC:
.git/config.refs/heads/../../config to SetReference.The matrix script runs the same PoC against v5.19.1 and v5.19.2 in temporary
modules without changing this repository's go.mod.
./scripts/run-version-matrix.sh
Expected classifications:
go-git v5.19.1
[!] VULNERABLE: .git/config was overwritten through the reference name.
go-git v5.19.2
[+] FIXED: the crafted reference was rejected and .git/config stayed intact.
Use -keep if you want to inspect the generated files. The displayed
directory is not automatically removed in that mode and must be deleted
manually after inspection.
go run . -keep
This PoC directly exercises the vulnerable filesystem-storage entry point described by the advisory and demonstrates metadata overwrite through path traversal. It does not implement a malicious Git protocol server or the clone/fetch transport path.
Upgrade v5 users to v5.19.2 or later and v6 alpha users to
v6.0.0-alpha.5 or later. Until an upgrade is possible, do not clone from or
fetch from untrusted Git servers with filesystem-backed storage. Applications
using only storage/memory are not affected.