Report privately through GitHub's advisory form. Please do not open a public issue for anything exploitable.
Include what you did, what happened, and what you expected. A failing test or a
short reproduction against a local registry:3 is the fastest route to a fix.
This is a personal, pre-1.0 project with no service-level commitment. Expect a first response within a couple of weeks.
The interesting attack surface is content fetched from a registry, because a registry is not a trust boundary: anyone who can push to a repository controls every byte a client later reads.
In scope:
- Registry-supplied data leading to code execution, path traversal, or writes
outside
$GIT_DIR. Manifests, annotations, packfiles, pack indexes, the pack chain, Git LFS pointers and object ids all arrive this way — every one of them is bytes chosen by whoever last pushed. - Resource exhaustion from hostile content, such as decompression bombs.
- Credentials leaking into logs, error messages, or the registry.
- A fetch that silently produces an incomplete or wrong object graph. Git's correctness depends on it, so we treat it as a security-adjacent bug even though it is not exploitable.
Out of scope:
- Advisory locking being bypassed. It is documented as advisory: registries offer no compare-and-swap, so it narrows races without closing them. See FORMAT.md §9.
- The absence of provenance. Nothing published here is signed by this tool, and
no annotation should be read as attesting to anything.
git push --signedis accepted so git does not error out and the certificate is recorded nowhere, because there is no server to verify one against. - Anything requiring push access to the repository being attacked. Someone who can push can already rewrite history.
- Vulnerabilities in registries, in
gititself, or in dependencies without a demonstrated path through this code.
Two invariants carry most of the weight, both in AGENTS.md and FORMAT.md:
- Every identifier from a registry is validated before use. Commit ids, LFS
object ids and ref names become tag names and filesystem paths. This applies
to whichever route the data arrived by: the same commit id is validated in the
pack-basesannotation and again in the pack chain blob, because the two are separate parsers of the same fact. - Data-loss failures are propagated, never downgraded to a warning. A missing pack base is a hard error precisely because nothing on the registry side verifies reachability.