CVE-2026-41145:Unsigned-Trailer 查询认证绕过
状态: 已发布
首个包含版本: RELEASE.2026-04-17T00-00-00Z
修复提交: f444b6f37
GitHub Advisory: GHSA-hv4r-mvr4-25vw
在 f444b6f37 之前,查询字符串(query-string)形式的 SigV4 凭据可以进入 STREAMING-UNSIGNED-PAYLOAD-TRAILER 上传流,但旧处理器仅在存在 HTTP Authorization 请求头时才执行签名验证。因此,攻击者只要知道一个有效的 Access Key ID,无需构造正确签名即可完成对象或分片写入。
最终修复将预签名请求拒绝与 SigV4 签名验证直接收口进 newUnsignedV4ChunkedReader()(cmd/streaming-v4-unsigned.go),让所有消费该分块数据流的调用方强制共用同一道认证边界。
提交编号说明
2026-04-16 编写补丁时正式 CVE 编号尚未分配,Git 提交标题临时写为 fake CVE-2026-40027。GHSA-hv4r-mvr4-25vw 发布后,正式编号确定为 CVE-2026-41145。历史提交对象 f444b6f37 保持原样,台账与文档统一使用正式编号。
根因:将签名验证绑定到了凭据传输形态
受影响入口包括 PutObject 与 PutObjectPart(UploadPart)。当请求指定 X-Amz-Content-Sha256: STREAMING-UNSIGNED-PAYLOAD-TRAILER,并将 SigV4 凭据与签名(X-Amz-Credential、X-Amz-Signature 等)放在 URL 查询字符串而非 Authorization 请求头中时,旧代码的两处假设发生了碰撞:
- 处理器用“
Authorization请求头是否非空”来决定是否调用reqSignatureV4Verify,误以为请求头为空就代表纯匿名请求; - 身份提取与
newUnsignedV4ChunkedReader()仍然照常读取分块请求体,并将该次写入归属到查询参数X-Amz-Credential指定的 Access Key 名下。
结果是:携带查询字符串凭据的 unsigned-trailer 请求跳过了签名校验,静默降级为“只要报出有效 Access Key 标识即可写入”。
为什么把守卫下沉到共享 Reader,而非逐个修补 Handler
| 候选方案 | 风险 | 结论 |
|---|---|---|
在 PutObject 与 PutObjectPart 中各自修补请求头/查询参数判断 |
仅闭合当前两个入口;其他或未来新增调用 newUnsignedV4ChunkedReader() 的入口极易再次漏检(正如 CVE-2026-40344 所示) |
否决 |
额外设计兼容预签名查询参数的 STREAMING-UNSIGNED-PAYLOAD-TRAILER 协议 |
在没有既有 S3 协议支持契约的情况下大幅扩张流式鉴权状态机与测试面 | 否决 |
在 newUnsignedV4ChunkedReader() 入口统一拒绝预签名凭据并强制验签 |
所有消费该数据流的调用方强制经过同一道认证门禁 | 接受 |
需要注意,纯匿名 STREAMING-UNSIGNED-PAYLOAD-TRAILER 请求并未被一刀切禁用:当请求未携带任何认证凭据、且目标桶策略(Bucket Policy)显式允许匿名 s3:PutObject 时,它仍按匿名授权路径正常工作。真正被禁止的是“携带了查询凭据,却未对该凭据执行验签”的混合状态。
实现与验证
提交 f444b6f37 在 cmd/streaming-v4-unsigned.go 的 newUnsignedV4ChunkedReader() 入口完成预签名拒绝与 SigV4 签名验证,同时移除了 PutObject 与分片上传处理器中依赖 Authorization 请求头是否存在的条件判断。
cmd 包新增的回归测试覆盖:
- 拒绝
STREAMING-UNSIGNED-PAYLOAD-TRAILER模式下伪造查询签名的PutObject与PutObjectPart请求; - 拒绝同时混用请求头与查询参数凭据的请求;
- 验证标准请求头认证的 unsigned-trailer 上传以及桶策略允许的纯匿名写入继续正常工作。
兼容性与运维边界
- 明确拒绝预签名 unsigned-trailer:预签名/查询字符串 SigV4 凭据与
STREAMING-UNSIGNED-PAYLOAD-TRAILER的组合现已明确不受支持,属于有意的不兼容收紧(Breaking Change)。 - 下沉至 Reader 的结构性收益:当多个处理器共享同一种认证数据流时,将认证门禁放进
newUnsignedV4ChunkedReader()能够从结构上防止PutObject、PutObjectPart或PutObjectExtract(CVE-2026-40344)再次因外层分支不一致而漏检。