GitHub Verified Badge Malleable: Same Code Yields Multiple Valid Commit Hashes
Jacob Ginesin of Carnegie Mellon discovered that GitHub’s “Verified” badge can be forged through signature malleability, allowing an attacker to create a second commit with identical tree and timestamp but a different hash, breaking the assumption that commit hashes are immutable identifiers for many downstream systems.
1. Vulnerability Overview
Jacob Ginesin, a PhD student at Carnegie Mellon University and a Cure53 auditor, disclosed a vulnerability in GitHub’s “Verified” badge in an arXiv paper (2607.02820) and released the open‑source tool git-chain-malleator.
The core issue is that GitHub treats the badge as proof that a commit is signed by a trusted author, but it does not treat the commit hash as a unique fingerprint. An attacker who can modify the signature bytes while keeping the signature valid can produce a second commit that is still marked Verified, has the same tree and timestamp, but a different commit hash.
This is not a hash collision; the underlying SHA‑1/SHA‑256 hashes remain intact. The malleability lies in the signature format itself.
2. Technical Analysis
2.1 Three signature‑malleation paths
ECDSA signature: algebraic transformation (s → n‑s) – Replacing the s component with n‑s (where n is the curve order) yields a different signature that still verifies locally with git verify-commit and on GitHub, so the commit receives the Verified badge.
RSA and EdDSA signatures: OpenPGP sub‑packet injection – Adding extra OpenPGP sub‑packets in the “unhashed” region of the signature (RFC 4880 5.2.3) changes the commit bytes and thus the hash, while the signature verification still passes.
S/MIME (X.509) signatures: non‑canonical DER length encoding – Re‑encoding the length fields in the CMS envelope to a longer but equivalent form breaks strict local gpgsm verification but GitHub still accepts the signature as Verified.
2.2 Root cause: GitHub does not normalise signatures
GitHub records the Verified status per commit hash without normalising the signature bytes. It therefore accepts any legally‑formed signature variant and does not cross‑check different hashes that represent the same content.
Pushing the original and the transformed commit to two branches makes GitHub’s compare view show “1 commit ahead, 1 commit behind” even though the content is identical.
2.3 Hash‑chain cascading effect
Because each commit points to its parent by hash, a malleated commit also changes the parent‑pointer hash. All descendant commits consequently receive new hashes, even though the file contents never change. The provided tool rewrites the entire chain and updates the branch pointer.
3. Impact Scope
Any system that treats the commit hash as an immutable identifier is affected, including:
Nixpkgs – package manager that deduplicates by commit hash.
Go modules – go.sum and pinning rely on immutable commit hashes.
GitHub Actions – workflows pin a specific commit to fetch code.
Docker/OCI image references – layers may embed commit hashes.
Reproducible builds – build records use commit hashes as content addresses.
Vendor security blocklists – blocklists that filter by commit hash.
Attack scenario: a security team blocks a malicious commit hash. An attacker uses the malleability tool to generate a new Verified commit with the same code, bypassing the blocklist.
Note: the attack does not inject new code; the author signature remains bound to the original author and the file contents are unchanged. What is broken is the trust model that treats the commit hash as a unique, immutable marker.
4. Fix Status
No CVE assigned.
No official GitHub fix announced.
No vendor security advisory.
The paper states that the flaw is a design defect at the Git‑forge layer and should be addressed by platforms such as GitHub.
5. Temporary Mitigations
Overlay a content hash (tree object hash or file‑level hash) on top of the commit hash for deduplication.
Downstream systems should not rely solely on the commit hash as a trust anchor after verifying the signature.
Add a content‑consistency check in CI/CD pipelines.
S/MIME users can use gpgsm with strict validation to block the DER re‑encoding attack, though it does not stop the ECDSA algebraic transformation.
6. Conclusion
The GitHub “Verified” badge does not guarantee uniqueness. Signature malleability allows the same source code to be represented by multiple distinct, still‑Verified commit hashes. This is a flaw in GitHub’s separation of signature verification from hash uniqueness, not a weakness in Git or the hash algorithms themselves.
Given the growing importance of software‑supply‑chain security, any workflow that treats a commit hash as an immutable identifier should reassess its trust assumptions.
Paper: https://arxiv.org/abs/2607.02820
Proof‑of‑concept tool: https://github.com/JakeGinesin/git-chain-malleator
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Black & White Path
We are the beacon of the cyber world, a stepping stone on the road to security.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
