GitHub 'Verified' Commits Can Be Rewritten Into New Hashes Without Breaking Signatures
GitHub 'Verified' commits can be rewritten with new hashes without breaking signatures.
Summary
New research reveals that GitHub's 'Verified' commit feature can be bypassed. Attackers can create a new commit with identical files, author, and date, but a different hash, which GitHub still marks as 'Verified' because it doesn't normalize signatures before checking. This malleability undermines systems relying on commit hashes for deduplication and provenance.
Full text
GitHub 'Verified' Commits Can Be Rewritten Into New Hashes Without Breaking Signatures Swati KhandelwalJul 08, 2026DevSecOps / Open Source Security New research shows that a signed Git commit's hash is not the one-of-a-kind name that much of the software world assumes it to be. Given any signed commit, someone without the signing key can mint a second commit with the same files, author, and date, and a valid signature, GitHub still stamps "Verified." Everything a reviewer would check matches. The commit's hash does not. That matters because so many systems treat a verified commit hash as a permanent, unique name for its contents. Here is the concrete failure: block a bad commit by its hash, and an attacker can re-push the same content under a fresh, still-"Verified" hash your blocklist has never seen. Deduplication, provenance logs, and reproducible-build records that key on the hash inherit the same soft spot. A compromised or hostile mirror can hand cloners validly signed commits whose hashes differ from those on the canonical forge. What this is not is a way to slip different code past a signature check. The files are identical in every copy, so a hash you pinned still fetches exactly the content you expected, or fails. There is no CVE and no vendor advisory, and nothing to change in your own repo: the flaw is in how a forge decides what "Verified" means, and the fix belongs on the forge's side. The work comes from Jacob Ginesin, a PhD student at Carnegie Mellon University and a cryptographic auditor at Cure53. His five-page paper, posted to arXiv on July 2, comes with a public tool that runs all three attacks, plus two demo repositories where the malleated commits still show "Verified" on GitHub. Because every commit names its parent by hash, malleating one commit forces new hashes on the commits above it. The tool rewrites that chain to keep it consistent. A signed descendant, though, loses its own badge the moment its parent pointer changes. Ginesin calls the effect "hash chain malleability." The cause is signature malleability. A commit's hash is computed over everything inside it, including the raw bytes of the signature in its header. Many signatures can be rewritten into a different but still-valid form, and changing those bytes changes the hash without touching a line of code. The three routes cover every GPG scheme GitHub verifies, plus S/MIME: ECDSA keys: flip the signature with a classic piece of elliptic-curve algebra (turn the value s into n - s). Both forms are valid. This passes a local git verify-commit and earns a GitHub badge. RSA and EdDSA keys: add an extra, ignored field to the signature's "unhashed" section, the part the signature deliberately does not cover. The signature still checks out, but the commit's bytes, and its hash, change. Local and GitHub both accept it. S/MIME (X.509) keys: rewrite a length field in the signature's DER structure into a longer, non-standard form. A strict local check (via gpgsm) rejects it, but GitHub still marks it "Verified," both of which the tool reproduces. The three routes share one enabler: GitHub does not normalize a signature before checking it. No strict encoding on S/MIME, no stripping of those OpenPGP fields, and non-canonical ECDSA values accepted as-is. GitHub then files a "Verified" record against each commit hash and does not re-check it, so a commit stays "Verified" even after its signing key is revoked. Push an original and its twin to two branches, and GitHub's compare view treats them as divergent histories, one commit ahead and one behind, despite identical files. To be clear: this is not a hash collision. It does not break SHA-1 or SHA-256, and has nothing to do with Git's move to SHA-256. Nobody is forcing two different commits to share one hash; it is the reverse, one commit that can be written many valid ways, each with its own hash. The core move is old. Bitcoin fought the exact same ECDSA symmetry years ago, when anyone could flip the s value in a transaction signature and change the transaction's ID without the owner's key. The fix was to accept only the "low-S" form, and later to move signatures out of the ID with SegWit. The paper's fixes rhyme with that: canonicalize the encoding before you trust the hash. A known lesson, not exotic new cryptography. The paper also connects this to the recent GitHub Actions tag hijacks, the 2025 tj-actions/changed-files and 2026 trivy-action attacks (it cites the latter). After those, the advice was simple: pin to a full commit hash, not a movable tag. That advice still holds. Pinning stopped those attacks, and this research does not change that. Its point is narrower. In the Trivy case, the malicious commits stood out because they could not be validly signed. This is a caution against leaning too hard on that tell: a valid signature proves who signed a commit, but it does not make the commit's hash a one-of-a-kind name for what it contains. So who has to do something? Not the developer pinning an Action or a module; a pinned hash still fetches the right code. The work is for the forges. The paper says they should canonicalize signatures before trusting them. Tooling that blocks, deduplicates, or records provenance by commit hash should do the same, verifying and canonicalizing first rather than trusting the raw hash of a signed object that an attacker can re-encode. Not all systems are equally exposed: schemes that also pin an independent hash of the fetched files, such as Nix's fixed-output derivations, keep a backstop; those that stop at a verified commit hash do not. Ginesin says he reported the issue to GNU and Git in January and to GitHub in March, and that as of the paper's publication, neither Git nor any forge had addressed it. The forge-side fix is well understood, and the obvious place to begin is the S/MIME case, where GitHub still accepts what a strict local check rejects. Found this article interesting? Follow us on Google News, Twitter and LinkedIn to read more exclusive content we post. SHARE Tweet Share Share Share SHARE Cloud security, code signing, cryptography, DevSecOps, Git Security, GitHub, Identity Security, Open Source Security, Software Supply Chain, Vulnerability ⚡ Top Stories This Week ThreatsDay: AI Compute Hijacking, Apple Email Flaw, BlueHammer Ransomware + 14 Stories Chrome Ad Blocker with 10M+ Installs Found with Dormant Script Injection Capability New DirtyClone Linux Kernel Flaw Lets Local Users Gain Root via Cloned Packets Amazon Q Developer Flaw Could Let Malicious Repos Run Code via MCP Configs New Linux pedit COW Exploit Enables Root Access by Poisoning Cached Binaries OpenAI Previews GPT-5.6 Sol With Restricted Access and Stronger Cyber Safeguards FBI Warns Russian Intelligence Hackers Target Signal Backup Recovery Keys Public PoC Released for Critical libssh2 CVE-2026-55200 Client-Side SSH Flaw Microsoft Removes 119 Edge Extensions That Hid Malware in Images and Fonts ⚡ Weekly Recap: Linux Kernel Flaws, AI Malware Tricks, Turla Backdoor, Infostealers and More Mustang Panda Uses Zoho WorkDrive as Command Channel in Indian Government Attacks WhatsApp is Finally Getting Usernames to Help Keep Phone Numbers Private Oracle E-Business Suite Flaw CVE-2026-46817 Actively Exploited in the Wild New BioShocking Attack Tricks AI Browsers Into Leaking User Credentials AirDrop and Quick Share Flaws Let Nearby Attackers Trigger Crashes and Bypass Checks 282 iOS AI Apps Leak API Keys and Open AI Proxy Access in Network Traffic Study GuardFall Exposes Open-Source AI Coding Agents to Decades-Old Shell Injection Risks Microsoft Warns Poisoned MCP Tool Descriptions Can Make AI Agents Leak Data RustDuck Botnet Rebuilds in Rust to Hijack Routers and Servers for DDoS ⭐ Featured Resources What 200+ Security Teams Reveal About Using IP Intelligence in 2026 Get Hands-On SANS Training for Today’s Cyber Defense and Offensive Security Challenges See What’s Really Exposed Across Your IT, OT, IoT, Cloud,