Attackers can silently clone “Verified” GitHub commits by abusing signature malleability in Git’s commit-signing formats, creating byte‑different commits with identical content, valid signatures, and fresh “Verified” badges under new hashes.
This breaks the long‑standing assumption that a verified commit hash is a unique, immutable identifier for a specific piece of signed content and exposes hash‑based blocking, dependency pinning, and reproducible‑build workflows to subtle supply‑chain attacks.
Duplicate Verified GitHub Commits
Git’s security model treats the commit hash as a content‑addressable identifier that covers the tree, parent list, author and committer metadata, commit message, and any embedded signature bytes in the gpgsig header.
Because the signature itself sits within the hashed region, changing its byte encoding without altering the logical content it attests to produces a different commit hash while leaving the tree and metadata untouched.
Verifiers only require “a valid signature” over the payload, not a unique canonical encoding of that signature, which creates room for an attacker to rewrite the commit’s serialized form while preserving successful verification.
Jacob Ginesin’s new work on “Git Hash Chain Malleability” shows three practical malleation routes that cover every GPG‑based signature scheme GitHub supports today: ECDSA, RSA, EdDSA, and S/MIME/CMS.
For ECDSA, a classical algebraic symmetry allows transforming a valid signature pair (r,s)(r,s)(r,s) into (r,n−s)(r, n – s)(r,n−s) using only public curve parameters, yielding a second, equally valid signature over the same commit payload with different bytes and thus a new hash.
For RSA and EdDSA under OpenPGP, the attack targets the unhashed subpacket region defined in RFC 4880 §5.2.3, appending an ignorable experimental subpacket.
Critically, GitHub’s server‑side verification accepts all three malleation techniques and records each malleated commit as an independent, durable “Verified” entry keyed solely on the new commit hash.
GitHub does not canonicalize OpenPGP or CMS containers before verification: it accepts non‑canonical ECDSA scalars, ignores advisory unhashed subpackets, and tolerates non‑DER CMS envelopes as long as the underlying signature validates, so the interface never signals that two “Verified” commits encode identical content.
In comparison views, an original and its malleated twin pushed to different branches can appear as “1 commit ahead and 1 commit behind” despite byte‑identical trees, reinforcing a deceptive sense of divergence.
This “hash chain malleability” cascades beyond individual commits because each Git commit names its parent by hash, so rewriting a signed commit forces all descendants to update their parent field and emit new hashes, even when their content does not change.
Ginesin provides proof‑of‑concept tooling that automatically detects the signature type in a gpgsig header, applies the appropriate malleation, rewrites descendant commits to maintain a consistent graph, and advances branch pointers to the new head.
Public demo repositories show both S/MIME‑signed and EdDSA‑signed commits that have been malleated in this way, each still carrying a valid GitHub “Verified” badge, as per reported by Arxiv.
The downstream impact on software supply chains is substantial. Hash‑based incident‑response controls and push‑protection rules that block known‑malicious commits by SHA can be bypassed simply by re‑pushing a ghost twin under a fresh, equally “Verified” hash that is not on the block list.
Dependency pinning mechanisms that rely on commit hashes, such as Nix flakes, Go module pseudo‑versions, pinned GitHub Actions SHAs, or Dockerfiles referencing specific commits, can be misled by mirrors that serve alternate, validly signed hash chains that deviate from the canonical forge yet appear trustworthy.
Reproducible‑build systems and provenance frameworks like SLSA that treat the commit hash as the ground‑truth revision identifier inherit this weakness wholesale: a “Verified” hash no longer uniquely identifies content, undercutting assumptions about immutable source and durable trust anchors used in logs like Sigstore’s Rekor.
Until such changes are widely deployed, the takeaway for defenders is stark: neither a signed commit nor a GitHub “Verified” badge can be treated as a unique identifier for a piece of content, especially in high‑assurance CI/CD and supply‑chain contexts.
Hash‑based deduplication, blocking, and pinning should occur after content canonicalization and signature verification, not directly on raw signed object bytes that an attacker can subtly manipulate.
Interact with Cyber Threats in Windows, Linux, macOS VMs to Trigger Full Attack Chain - Analyse Malware & Phishing with ANY RUN

