
Локальное доказательство концепции для CVE-2026-71557, демонстрирующее обход пути в хранилище ссылок файловой системы go-git, включая логику эксплуатации и сравнение уязвимой и исправленной версий.
Этот репозиторий содержит безопасный локальный PoC для CVE-2026-71557 на основе публичного advisory go-git GHSA-qgq7-7hm3-q39j.
До исправления storage/filesystem недостаточно проверял имена loose reference и использовал их как путь .git/<reference-name>. Из-за этого передача имени ссылки вида refs/heads/../../config приводила к нормализации .., что позволяло перезаписать .git/config за пределами штатного reference storage.
Этот PoC вызывает реальные API go-git и воздействует только на фиктивный .git/config, созданный во временном каталоге. Он не подключается к внешним Git-серверам, не изменяет существующие репозитории и не выполняет произвольные команды.
Этот проект предназначен исключительно для образовательных целей и разрешённых этичных проверок безопасности. Не используйте его в средах без соответствующего разрешения.
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 в storage/filesystemstorage/memoryВ v5.19.1 до исправления DotGit.SetRef передавал имя ссылки в setRef непосредственно как имя файла.
fileName := r.Name().String()
return d.setRef(fileName, content, old)
Корнем filesystem-backed storage обычно является .git. Имя ссылки refs/heads/../../config после нормализации пути превращается в config, поэтому запись значения ссылки превращается в запись .git/config. Если вредоносный Git-сервер рекламирует такое имя ссылки, и после маппинга refspec при clone/fetch traversal сохраняется, управляемое атакующим имя ссылки может достичь этого пути кода.
Исправленная версия проверяет имена ссылок на входах SetRef, Ref, RemoveRef и других в filesystem storage и отклоняет имена, выходящие за пределы reference storage.
go.mod зафиксирован на уязвимой версии v5.19.1.
go run .
Ожидаемый основной вывод:
[*] go-git version: v5.19.1
[*] crafted reference: refs/heads/../../config
[*] SetReference error: <nil>
[!] VULNERABLE: .git/config was overwritten through the reference name.
PoC выполняет следующие действия:
.git/configrefs/heads/../../config в SetReferenceСледующий скрипт не изменяет go.mod в репозитории, а с помощью временного модуля последовательно запускает тот же PoC на v5.19.1 и v5.19.2.
./scripts/run-version-matrix.sh
Ожидаемый результат:
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.
Если нужно просмотреть временные файлы, добавьте -keep. Указанные каталоги не удаляются автоматически, поэтому после проверки удалите их вручную.
go run . -keep
Этот PoC напрямую вызывает уязвимые входы filesystem storage, описанные в advisory, и проверяет перезапись метаданных через path traversal. Вредоносный Git protocol server и транспортный уровень clone/fetch в нём не реализованы.
Пользователям v5 следует обновиться до v5.19.2 или новее, пользователям v6 alpha — до v6.0.0-alpha.5 или новее. Если обновление невозможно, не выполняйте clone/fetch с недоверенных Git-серверов в filesystem-backed storage. Приложения, использующие только storage/memory, данной уязвимостью не затронуты.