Pith. sign in

REVIEW 3 major objections 5 minor 1 cited by

Git Hash Chain Malleability

T0 review · 3 major / 5 minor · reviewed 2026-07-12 · grok-4.5

Pith's one-line read Any signed Git commit can be turned into a different hash that still verifies and earns a GitHub Verified badge, without the signing key or breaking SHA-2.

desk verdict Solid, reproducible demonstration that every GitHub-supported signed-commit scheme admits keyless hash-changing malleation that still gets a Verified badge. read the letter →

arxiv 2607.02820 v2 pith:NVMCE3WR submitted 2026-07-02 cs.CR

classification cs.CR
keywords gitcommitsigninghashmalleabilityECDSAOpenPGPS/MIMEsupply-chainsecuritycontentaddressing
verification ladder T0 review T1 audit T2 compute T3 formal

The pith

A machine-rendered reading of the paper's core claim, the machinery that carries it, and where it could break.

The reading

Git is trusted to treat a signed commit hash as a unique, immutable name for specific content. This paper shows that trust is misplaced. An attacker who never obtains the private key can rewrite only the signature container of a signed commit so the hash changes while the tree, parents, metadata, and verification result stay the same; GitHub still awards an independent Verified badge to the new hash. Because later commits name their parents by hash, the change rewrites the entire dependent chain—the authors call this hash chain malleability. The finding matters for every system that pins, blocks, or attests by commit hash: those systems are treating a non-unique encoding as a content-addressable primary key.

What carries the argument

Hash chain malleability: because the raw signature bytes sit inside the hashed commit object, any change that preserves semantic signature validity changes the commit hash while leaving tree and metadata untouched. The paper supplies three concrete routes—(i) ECDSA s ↦ n−s, (ii) insertion of an unhashed OpenPGP subpacket, (iii) non-canonical DER length re-encoding in the CMS envelope—each of which GitHub accepts.

What would settle it

Run the paper’s published malleator on any publicly signed commit, push the resulting ghost object to a GitHub branch, and check whether the new hash receives its own independent Verified badge while the tree and message remain byte-identical to the original.

Watch

Extended reading notes

Core claim

Given any signed commit, an attacker without the signing key and without breaking SHA-2 can produce a second, distinct commit that carries an identical tree, identical metadata, a valid signature, and a persistent independent Verified badge on GitHub, differing only in its commit hash. The rewrite cascades through every descendant, so the entire dependent hash chain is malleable. Three routes cover every signature scheme GitHub verifies for commits: ECDSA algebraic inversion, OpenPGP unhashed-subpacket insertion, and CMS non-canonical DER length re-encoding.

Load-bearing premise

Signature verifiers (and GitHub’s server-side checker) accept any semantically valid encoding rather than requiring a single canonical byte form before they compute the commit hash or issue a Verified record.

Editorial extensions

If this is right

  • Hash-based blocking or reversion of a malicious commit can be silently bypassed by re-pushing a content-identical, still-Verified malleated twin.
  • Dependency pins that lock to a commit SHA (Go modules, Nix flakes, GitHub Actions, Dockerfiles) no longer uniquely name signed content under a given signer.
  • Reproducible-build and provenance systems that treat the commit hash as the primary revision identifier inherit a non-unique trust anchor.
  • An attacker with push access can force-push release tags onto malleated chains while GitHub continues to display Verified badges.
  • GitHub’s persistent verification records, keyed only by hash, allow one logical commit to appear under an unbounded family of independently Verified hashes.

Reading between the lines

Editorial extensions of the paper, not claims the author makes directly.

  • Forges that canonicalize signature containers (low-s ECDSA, strip unhashed OpenPGP subpackets, enforce DER) before hashing or verification would close the attack without changing the cryptographic schemes themselves.
  • The same encoding gaps likely affect any other content-addressed store that embeds OpenPGP or CMS signatures inside the hashed object.
  • Pinning schemes that already pair the commit hash with an independent tree content hash retain a residual integrity check the pure-hash schemes lack.
  • The SHA-256 migration for Git object names does not mitigate the issue, because the attack never relies on hash collisions.
Share X Bluesky LinkedIn Reddit HN

Editorial analysis

A structured set of objections, weighed in public.

Desk editor's note, referee report, and a circularity audit.

Referee Report

3 major / 5 minor

Summary. The paper demonstrates that a signed Git commit is not a unique, immutable content identifier: without the private key and without breaking SHA-2, an attacker can produce a second commit object that has an identical tree and metadata, carries a still-valid signature, receives a GitHub “Verified” badge, and differs only in its commit hash. Three concrete routes are given—ECDSA algebraic inversion (s ↦ n−s), OpenPGP unhashed-subpacket insertion (RFC 4880 §5.2.3) for RSA/EdDSA, and non-canonical DER length re-encoding (X.690 §10.1) inside CMS/S/MIME—covering every scheme GitHub currently verifies. Because the signature bytes lie inside the hashed region, the new hash cascades to every descendant, which the authors term “hash chain malleability.” Table 1 records local versus GitHub acceptance; public PoC tooling and example repositories are supplied; and consequences for hash-based blocking, dependency pinning, and reproducible-build systems are discussed.

Significance. If the result holds, a widely trusted invariant of supply-chain tooling is false: a “Verified” commit hash cannot be treated as a unique primary key. The work is concrete, reproducible (Nix flake, public GitHub demos for EdDSA and S/MIME, automated graph rewriter), and rests on standard, independently specified properties rather than new cryptanalysis. Credit is due for shipping working tooling that rewrites entire commit graphs and for cleanly separating the three malleation layers. The findings directly affect Nixpkgs, Go modules, GitHub Actions pins, SLSA source track, and Sigstore/gitsign, all of which currently treat the raw commit hash as authoritative. Even if forges later canonicalize, the paper correctly documents the present state and the residual risk for any consumer that does not canonicalize before hashing.

major comments (3)
  1. [§6 / Abstract] §6 and the abstract claim that malleation of one commit “cascades” to a well-formed rewrite of all descendants while preserving the overall phenomenon of hash-chain malleability. Changing a parent hash alters the signed payload of every descendant. Because malleation only produces an alternate signature for an identical payload, the rewritten descendants lose signature validity unless the attacker possesses the signing key and re-signs. The paper never states whether the supplied rewriter (a) drops signatures, (b) leaves broken signatures, or (c) somehow preserves them. This distinction is load-bearing for the “hash chain” terminology and for any impact that assumes a fully Verified rewritten history.
  2. [§5] §5 “Bypass of immutable releases” asserts that an attacker with push access can construct a parallel chain of commits that retain “Verified” badges after force-pushing tags. For any multi-commit history the same payload-change problem arises: each rewritten descendant requires a fresh signature over the new parent list. Without the private key this is impossible. The claim therefore holds only for a single tagged commit, not for a chain. The section should be narrowed or the experimental evidence that multi-commit Verified chains can be produced should be supplied.
  3. [§5] §5 further claims that a malleated commit “earns its own independent log entry” in Sigstore/Rekor and thereby duplicates the SLSA/gitsign trust anchor. The provided PoCs and example repositories demonstrate only GitHub’s verifier and local git/gpgsm; no Rekor submission or SLSA provenance experiment is reported. Because the impact argument treats the independent log entry as fact, either a concrete demonstration or a clear “conjectured” qualifier is required.
minor comments (5)
  1. [Abstract / §1] Throughout the extracted text many words are concatenated (“pieceofsignedcontent”, “Weshowthisinvariant//ldots”). Assuming this is an extraction artifact, the camera-ready version should be checked for proper spacing and line breaks.
  2. [Table 1] Table 1 caption and body are clear, but the column “Local” should explicitly name the tools (git verify-commit vs. gpgsm) so readers do not have to hunt in the text.
  3. [§3.1] §3.1 states that curve order is inferred from scalar bit length. A one-sentence note on how P-521’s non-byte-aligned order is handled would remove a minor ambiguity for implementers.
  4. [§4] Reference [7] (GitHub docs on persistent verification) is cited for the claim that records are never re-evaluated; a short quotation or archive link would make the claim more durable.
  5. [§10] The ethics statement lists disclosure dates in 2026 while the arXiv stamp is also 2026; a single consistent timeline sentence would avoid reader confusion.

Circularity Check

0 steps flagged · score 0.0 of 10

No circularity: existence demonstration of known signature malleability applied to Git commit serialization, validated against external verifiers and independent standards.

full rationale

The paper's central claim is an existence result: given a signed Git commit, three standard malleation techniques (ECDSA algebraic inversion s o n-s, OpenPGP unhashed subpacket insertion per RFC 4880 §5.2.3, and CMS non-canonical DER length re-encoding per X.690 §10.1) produce a byte-distinct commit with identical tree/metadata, a still-valid signature, and a GitHub Verified badge, cascading to descendant hashes. These techniques are classical properties of the schemes and encodings, not fitted parameters or self-defined quantities. Validation is external: local git verify-commit / gpgsm and GitHub's server-side verifier (Table 1, §4, public PoC repos). Background citations (ANSI X9.62, RFC 4880, RFC 5652, X.690, BIP-62) are independent standards, not author-overlapping uniqueness theorems or ansatzes. No prediction is obtained by fitting to data; no quantity is defined in terms of itself; the result is not a renaming of a known empirical pattern. The derivation is self-contained against external benchmarks, so circularity score is 0.

Assumptions & free parameters 0 free parameters · 5 assumptions · 1 invented entities

The paper is an applied cryptographic demonstration. It imports standard scheme and encoding properties and does not fit free parameters or invent new physical/cryptographic entities. Load-bearing content is almost entirely domain assumptions from RFCs, ANSI ECDSA, and observed forge behavior.

assumptions (5)
  • standard math For ECDSA over order-n curve, (r, n-s) verifies iff (r, s) does, because verification uses only the x-coordinate of the recovered point.
    Classical ECDSA property used in §3.1; also the basis of BIP-62.
  • domain assumption OpenPGP v4 unhashed subpackets are excluded from the signed digest (RFC 4880 §5.2.3) and non-critical private/experimental types must be ignored.
    Structural malleation route in §3.2 depends entirely on this RFC rule.
  • domain assumption CMS/S/MIME signatures are ASN.1; DER requires shortest length form (X.690 §10.1) while BER accepts long form, so non-canonical lengths can still verify under permissive parsers.
    Encoding malleation route in §3.3.
  • domain assumption Git commit object hash covers the full serialization including the gpgsig header, while the signed payload is the commit with gpgsig removed.
    Stated in §2; this is the precondition that any signature-byte change changes the commit hash.
  • domain assumption GitHub's server-side verifier does not canonicalize OpenPGP unhashed regions, ECDSA scalars, or CMS DER before verifying, and persists Verified records keyed by commit hash without re-evaluation.
    Empirical forge behavior reported in §4 and Table 1; required for the supply-chain impact claims.
invented entities (1)
  • hash chain malleability (terminology)
    purpose: Name the cascade of descendant commit-hash changes caused by malleating an ancestor signature.
    Terminological label only; no new cryptographic object is postulated. independent_evidence is false because it is a name, not a physical entity.

how reviews work

0 comments
Cite this review

Pith. "Pith review of Git Hash Chain Malleability." pith.science (2026). https://pith.science/paper/NVMCE3WR

@misc{pith2026260702820,
  author       = {Pith},
  title        = {Pith review of: Git Hash Chain Malleability},
  year         = {2026},
  howpublished = {\url{https://pith.science/paper/NVMCE3WR}},
  note         = {Machine review of arXiv:2607.02820}
}
read the original abstract

Git commit signing is widely entrusted to serve as evidence that a commit hash uniquely and immutably identifies a specific piece of signed content. We show this invariant does not hold. Given any signed commit, an attacker without access to the signing key, and without breaking SHA2, can produce a second, distinct commit with an identical tree, identical metadata, a valid signature, and a ``Verified'' badge from a Git Forge such as Github, differing only in its commit hash. The modified commit cascades to modify the values of all the subsequent, dependent commit hashes; hence we introduce the terminology ``hash chain malleability'' to describe this phenomenon. The malleability in signed Git hashes is feasible due to the inherent malleability present in many of the data representations that make up a commit. In this paper we show three such malleation routes: (i) algebraic inversion s -> n-s for ECDSA; (ii) structural insertion of an unhashed OpenPGP subpacket (RFC4880 5.2.3) for RSA and EdDSA; and (iii) non-canonical DER length re-encoding (X.690 10.1) inside the CMS envelope for S/MIME. Algebraic inversion for ECDSA signatures and subpacket insertion were found to pass local verification (git verify-commit), and all three methods yield a persistent, independent ``Verified'' record on Github. We discuss the consequences of Git hash chain malleation for hash-based commit blocking, dependency pinning (Nixpkgs, Go modules, Github Actions), and reproducible-build systems that treat the commit hash as a content-addressable primary key, and we provide proof-of-concept tooling that automates all three routes.

Discussion (0). Continue with ORCID to comment.

Forward citations

Cited by 1 Pith paper

Reviewed papers in the Pith corpus that reference this work. Sorted by Pith novelty score. Full citation record

  1. Canonicalization Failures as a Recurring Vulnerability Class: Representation Divergence in Cryptographic Systems and Its Avoidance

    cs.CR 2026-08 conditional novelty 4.0 of 10

    A cross-ecosystem taxonomy unifies canonicalization failures into one violated uniqueness condition with two break directions, plus a review checklist.

Pith tools

Reviewed July 12, 2026 · model on record in the stance chip above.