
Prova de conceito local para CVE-2026-71557 demonstrando travessia de caminho no armazenamento de referências do sistema de arquivos do go-git, incluindo lógica de exploit e comparação entre versões vulnerável e corrigida.
Este repositório é um PoC local e seguro da CVE-2026-71557, baseado no advisory público do go-git GHSA-qgq7-7hm3-q39j.
Antes da correção, o storage/filesystem não validava suficientemente o nome das loose references e o usava como caminho .git/<reference-name>. Por isso, ao passar um nome de referência como refs/heads/../../config, os .. eram normalizados, permitindo sobrescrever o .git/config, que fica fora do reference storage original.
Este PoC chama a API real do go-git e tem como alvo apenas um .git/config fictício criado em um diretório temporário. Ele não se conecta a servidores Git externos, não modifica repositórios existentes nem executa comandos arbitrários.
Este projeto destina-se exclusivamente a fins educacionais e a testes de segurança éticos autorizados. Não o utilize em ambientes sem permissão.
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 do storage/filesystemstorage/memoryNa v5.19.1, anterior à correção, o DotGit.SetRef passava o nome da referência diretamente como nome de arquivo para setRef.
fileName := r.Name().String()
return d.setRef(fileName, content, old)
A raiz do storage com suporte a filesystem normalmente é .git. O nome de referência refs/heads/../../config torna-se config após a normalização do caminho; portanto, a gravação do valor da referência transforma-se na gravação de .git/config. Se um servidor Git malicioso divulgar um nome de referência como esse e o traversal permanecer após o mapeamento de refspec durante clone/fetch, um nome de referência controlado pelo atacante pode chegar a esse caminho de código.
A versão corrigida valida o nome da referência em pontos de entrada do filesystem storage, como SetRef, Ref e RemoveRef, e rejeita nomes que saiam do reference storage.
O go.mod está fixado na versão vulnerável v5.19.1.
go run .
Saída principal esperada:
[*] go-git version: v5.19.1
[*] crafted reference: refs/heads/../../config
[*] SetReference error: <nil>
[!] VULNERABLE: .git/config was overwritten through the reference name.
O PoC realiza o seguinte:
.git/configrefs/heads/../../config para SetReferenceO script a seguir executa o mesmo PoC com v5.19.1 e v5.19.2 em sequência, usando módulos temporários, sem alterar o go.mod do repositório.
./scripts/run-version-matrix.sh
Resultado esperado:
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.
Se quiser inspecionar os arquivos temporários, use -keep. Os diretórios exibidos não são removidos automaticamente; portanto, remova-os manualmente após a inspeção.
go run . -keep
Este PoC valida a sobrescrita de metadados por path traversal chamando diretamente a entrada vulnerável do filesystem storage descrita no advisory. Ele não implementa um servidor de protocolo Git malicioso nem a camada de transporte de clone/fetch.
Usuários do v5 devem atualizar para v5.19.2 ou posterior; usuários do v6 alpha, para v6.0.0-alpha.5 ou posterior. Enquanto não for possível atualizar, não faça clone/fetch de servidores Git não confiáveis usando storage com suporte a filesystem. Aplicações que utilizam apenas storage/memory não são afetadas por esta vulnerabilidade.