CVE-2026-44309Gitsign是一款利用GitHub/OIDC身份对Git提交进行无密钥Sigstore签名的工具。在0.16.0版本之前,gitsign verify和gitsign verify-tag在验证签名前,会使用go-git的EncodeWithoutSignature重新编码提交或标记对象,而不是直接验证原始Git对象字节。对于包含重复树头部的畸形对象,git-core和go-git的解析逻辑不同:git-core使用第一个树,而go-git使用第二个。攻击者可以针对go-git规范化形式(即第二个树)制作恶意签名,该签名能通过gitsign verify的验证,但git-core会将提交解析为完全不同的第一个树。这破坏了已验证签名、git-core呈现给用户的提交语义以及Rekor中记录的对象哈希值均指向相同内容的不变量,导致签名验证机制失效。
该漏洞的根本原因在于Gitsign使用的go-git库与标准Git(git-core)在处理畸形Git对象时的解析逻辑不一致。漏洞利用了Git对象解析中的差异:当Git提交对象中包含重复的“tree”头部行时,git-core默认采纳第一个出现的tree哈希值,而go-git库则采纳最后一个。Gitsign在验证流程中,为了提取和校验签名,对对象进行了规范化处理(重新编码)。攻击者通过构造一个包含两个不同tree哈希的提交对象(第一个为恶意代码树,第二个为正常代码树),并针对go-git解析出的第二个tree进行签名。当Gitsign验证时,它读取的是第二个tree并验证通过;然而,当开发者或CI/CD系统使用标准git命令检出代码时,实际执行的是第一个tree对应的恶意代码。这种差异使得攻击者能够在维持有效签名外观的情况下,植入并执行未经授权的代码,严重破坏了软件供应链的完整性。