跳转到主要内容

CVE-2026-34204:复制元数据注入

普通 PUT 与 COPY 请求可将 X-Minio-Replication-* 请求头混入内部 SSE 与复制元数据;提交 56fa63b 默认剥离不可信请求头,仅在通过 ReplicateObjectAction 授权的复制路径中显式恢复。

状态: 已发布
首个包含版本: RELEASE.2026-04-17T00-00-00Z
修复提交: 56fa63b
GitHub Issue: pgsty/silo#24

在 56fa63b 之前,普通 PutObject 与 CopyObject 请求可以把客户端传入的 X-Minio-Replication-* 请求头混入内部 X-Minio-Internal-* SSE 与复制元数据,写出复制状态与真实授权路径不符、甚至后续无法读取的对象。

最终修复在默认元数据提取路径中不再接受复制专用元数据,仅在通过 ReplicateObjectAction(s3:ReplicateObject)授权的可信复制流程中显式恢复,并在 CopyObject 的所有前置请求头消费者执行之前统一完成清洗。

威胁模型

触发该漏洞只需要普通的对象写入权限(s3:PutObject),不需要节点间凭据或复制专用权限。攻击输入完全来自客户端可控的 X-Minio-Replication-* 请求头,但旧版元数据提取函数在未校验调用方是否具备复制权限的情况下,直接将它们转换成了内部复制或 SSE 状态。

当后续 GetObject 或 HeadObject 请求读取该对象时,服务端会按照伪造的内部状态解析或解密对象,从而导致读取失败,造成对象完整性与可用性破坏。几乎所有接受不可信写入的生产集群都受此影响。

问题的核心在于:来自不可信客户端的请求头在未通过复制授权检查前,就获得了内部特权语义。

为什么选择精确清洗,而非直接拒绝整条请求

最直观的修法是:只要普通请求携带了 X-Minio-Replication-* 请求头,就直接报错拒绝。但这样做会把客户端过去夹带的多余请求头从“被服务端忽略”变成硬失败,无谓地扩大兼容性影响面。

因此我们采用了“默认剥离、授权后恢复”的模型:

  • cmd/handler-utils.go 中的默认元数据提取路径不接受任何复制专用元数据;
  • 普通 PutObject 与 CopyObject 请求在构造元数据前先剥离这些字段;
  • 只有通过 ReplicateObjectAction 授权的代码分支才会显式恢复复制专用元数据;
  • 副本状态(replica status)写入共用同一可信授权条件;
  • 合法的分片上传与 Snowball 复制流程在通过授权后显式恢复所需的 SSE 元数据。

这样既彻底阻断了未授权注入,又不会破坏携带多余请求头的普通客户端。

为什么 CopyObject 必须在 cleanMetadata 之前提前清洗

在 CopyObject 中,请求头并非只在最后构造目标对象元数据字典(cleanMetadata)时才被读取,前置条件(Precondition)检查与 SSE-C 源对象密钥处理都会更早读取请求头。

如果等到即将写入目标对象前才剔除不可信的 X-Minio-Replication-* 请求头,早期的消费者就已经被伪造字段污染。把请求头清洗前移到 CopyObject 入口、位于所有前置条件与 SSE-C 处理逻辑之前,才能将“不可信复制请求头绝不进入内部语义”收敛为单一不变量,而不必依赖下游每个函数各自重复防御。

实现与验证

提交 56fa63b 修改了 cmd/handler-utils.go、对象处理器与分片上传处理器,并配套了多层回归测试:

  • 辅助函数层的可信与不可信元数据提取单元测试;
  • 处理器层携带恶意 X-Minio-Replication-* 请求头的 PutObject 与 CopyObject 用例;
  • 验证 CopyObject 前置条件与 SSE-C 路径不会读到未授权复制请求头的入口清洗测试;
  • 端到端验证:确认恶意请求头不再产生不可读对象,同时合法复制、分片上传与 Snowball 复制流程保持正常。
go test ./cmd -run 'Test.*Replication.*Metadata|Test.*CopyObject.*' -count=1

设计取舍与后续接收端全局加固

  • 默认静默剥离:普通客户端夹带的内部复制请求头会被直接剥离并忽略。
  • 安全的失效默认方向:由于复制专用元数据必须在授权分支内显式恢复,未来若新增复制入口时漏掉恢复调用,只会表现为功能测试失败,而不会静默放开未授权注入。
  • 后续接收端全局加固:
    • SN-2026-008(RELEASE.2026-09-03T13-18-01Z) 与 CORS 及复制信任设计记录 将这一模式推广为接收端统一的认证后信任边界,覆盖全部内部复制请求头(X-Minio-Source-Etag、X-Minio-Source-Mtime、X-Minio-Source-Replication-Request、复制 SSE 密钥头与 X-Amz-Bucket-Replication-Status)以及 SSE-C 读取、源时间戳、分片合并、对象锁、删除与事件通知。
    • 副本元数据规范化(RELEASE.2026-09-16T00-00-00Z,PR #194) 进一步确保:即便在已授权的可信复制 CopyObject 路径中,服务端也会规范化仅属于传输层的 aws-chunked Content-Encoding 并剔除已废弃的敏感元数据键,防止原始请求头被重新注入落盘对象。