libgit2 `git_reference_remove` accepts non-reference names and deletes control files
libgit2 1.9.7 accepts arbitrary filesystem-valid names in git_reference_remove() instead of requiring a Git reference name. In the attached reproduction, calls with HEAD, config, description, index, and logs/HEAD all return success and remove the corresponding files from the repository control directory. The object-based git_reference_delete() path rejects HEAD, while the delete-by-name path does not. Audited upstream main snapshot 0551dfd4ad989b6a3d5683c0d4cf326c6efef929 retains the same source path.
An application that passes an untrusted value to a generic reference-removal operation can therefore delete repository configuration, staged worktree state, reflog history, or HEAD with one API call. Removing HEAD can make subsequent repository operations fail; removing config can discard remotes and repository policy settings.
The closest adjacent behavior is git_reference_delete(), which rejects HEAD; the name-based git_reference_remove() API follows a separate path and accepts the control-file names shown above.
The attached report.md contains the source analysis and Git core comparison. attachments.zip contains a checksum-pinned Docker build, standalone C reproducer, and sanitized evidence.
Source: libgit2/libgit2