fix: authorize SSE-C attribute reads by replication permission

GetObjectAttributes lets a replication peer read SSE-C attributes without
presenting the customer key. That carve-out was keyed on the
X-Minio-Source-Replication-Request header alone, which any client can set,
so a caller holding only s3:GetObject could read an SSE-C object's ETag,
plaintext size, part list, and checksums without the key -- the response was
byte-identical to one made with the correct key.

Gate the carve-out on s3:ReplicateObject for the target object, mirroring
CopyObjectHandler's existing replication check.

The pre-existing test asserted the carve-out with root credentials, which
hold every action and therefore cannot tell a gated check apart from an
ungated one. Add least-privilege cases that do: a reader without
s3:ReplicateObject is now refused, a caller that holds it keeps the
carve-out, and the ordinary key-bearing path is unchanged.

Signed-off-by: Feng Ruohang <rh@vonng.com>
This commit is contained in:
Feng Ruohang
2026-08-30 15:50:24 +08:00
parent 1be684ba29
commit 74c97d005d
2 changed files with 145 additions and 1 deletions
+6 -1
View File
@@ -619,7 +619,12 @@ func (api objectAPIHandlers) getObjectAttributesHandler(ctx context.Context, obj
if checkPreconditions(ctx, w, r, objInfo, opts) {
return
}
if crypto.SSEC.IsEncrypted(objInfo.UserDefined) && r.Header.Get(xhttp.MinIOSourceReplicationRequest) != "true" {
// Only a caller authorized to replicate this object may read SSE-C
// attributes without presenting the customer key. The header alone is
// client controlled, so it cannot stand in for that authorization.
trustedReplicationRequest := r.Header.Get(xhttp.MinIOSourceReplicationRequest) == "true" &&
checkRequestAuthType(ctx, r, policy.ReplicateObjectAction, bucket, object) == ErrNone
if crypto.SSEC.IsEncrypted(objInfo.UserDefined) && !trustedReplicationRequest {
if _, err = crypto.SSEC.UnsealObjectKey(r.Header, objInfo.UserDefined, bucket, object); err != nil {
writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL)
return