GitHub ‘Verified’ Commits Vulnerable to Hash Manipulation

Recent research has uncovered a significant vulnerability in GitHub’s commit verification process, revealing that signed Git commits can be altered to produce new hashes without invalidating their ‘Verified’ status. This discovery challenges the long-held assumption that a commit’s hash serves as a unique identifier for its content.

In Git, each commit is assigned a unique hash based on its content, author, date, and signature. This hash is traditionally considered immutable and serves as a reference point for various systems, including blocklists, deduplication processes, and provenance logs. However, the new findings demonstrate that it’s possible to create a second commit with identical files, author, and date, yet with a different hash, while still retaining a valid signature. GitHub continues to display these altered commits as ‘Verified.’

This vulnerability poses several risks:

  • **Bypassing Blocklists**: If a malicious commit is blocked by its hash, an attacker can reintroduce the same content under a new, ‘Verified’ hash that the blocklist doesn’t recognize.
  • **Compromised Deduplication and Provenance Logs**: Systems relying on commit hashes for deduplication or tracking the origin of code may be misled by these altered hashes, undermining their reliability.
  • **Mirror Repository Risks**: Malicious or compromised mirrors can present cloned repositories with validly signed commits that have different hashes from those on the original repository, potentially leading to trust issues.

It’s important to note that this vulnerability doesn’t allow for the introduction of different code under the guise of a valid signature. The content remains unchanged; only the commit hash is different. Therefore, if a system fetches content based on a specific hash, it will still retrieve the expected content or fail if the hash doesn’t match.

The root cause of this issue lies in GitHub’s handling of commit signatures. The platform doesn’t normalize signatures before verification, allowing for variations that lead to different commit hashes. Specifically:

  • **ECDSA Keys**: By altering the signature using elliptic-curve algebra (changing the value ‘s’ to ‘n – s’), a valid but different signature is produced. Both forms pass GitHub’s verification.
  • **RSA and EdDSA Keys**: Adding an extra, ignored field to the signature’s ‘unhashed’ section changes the commit’s bytes and hash without affecting the signature’s validity.
  • **S/MIME (X.509) Keys**: Modifying a length field in the signature’s DER structure to a non-standard form results in a different hash. While strict local checks might reject this, GitHub still marks it as ‘Verified.’

These methods exploit the fact that GitHub doesn’t enforce strict encoding or normalization of signatures, allowing for multiple valid representations that lead to different commit hashes.

Addressing this vulnerability requires changes on GitHub’s end. Developers and repository maintainers should be aware of this issue, especially when relying on commit hashes for security measures. Until GitHub implements stricter signature verification and normalization processes, the integrity of commit hashes as unique identifiers remains compromised.

This revelation underscores the need for continuous scrutiny of security mechanisms in software development platforms. As GitHub is a central hub for open-source projects, ensuring the reliability of commit verification processes is paramount to maintaining trust and security within the developer community.