From 0c46cb641ba67adc86b46856df5f9c7bd2fef80e Mon Sep 17 00:00:00 2001 From: Feng Ruohang Date: Thu, 10 Sep 2026 09:57:26 +0800 Subject: [PATCH] docs(security): record SN-2026-011 (unsigned x-amz-* header CopyObject) Ledger entry for the confused-deputy fix in 123325430: an unsigned x-amz-copy-source header turned a presigned or signed PUT into a server-side copy of any object the signing key can read. Reported by Oren Yomtov; inherited from upstream minio/minio; CVE requested. Co-Authored-By: Claude Opus 4.8 Signed-off-by: Feng Ruohang --- docs/security/advisories.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/security/advisories.md b/docs/security/advisories.md index 7ac4b2364..e531ba22b 100644 --- a/docs/security/advisories.md +++ b/docs/security/advisories.md @@ -33,6 +33,7 @@ The first Silo community release was cut from upstream history that already cont | `SN-2026-008` | [PR #101](https://github.com/pgsty/silo/pull/101) ([`938603458`](https://github.com/pgsty/silo/commit/938603458) through [`04b097fd9`](https://github.com/pgsty/silo/commit/04b097fd9)) | Internal replication request headers such as `X-Minio-Source-Etag`, `X-Minio-Source-Mtime`, `X-Minio-Source-Replication-Request`, the replication SSE key headers, and `X-Amz-Bucket-Replication-Status` on object reads, writes, multipart uploads, deletes, Snowball extraction, and bucket events | Yes; any authenticated principal that can read or write the object | Completes CVE-2026-34204. The server still trusted these internal headers on presence in most handlers: any client could preserve arbitrary ETags and modification times, read SSE-C ciphertext without the key, inject replication checksums and Object Lock timestamps, suppress bucket notifications, and route deletes as replication deletes. | Replication semantics now require the exact marker value together with `s3:ReplicateObject` or `s3:ReplicateDelete`; other requests have these headers removed after signature verification and are processed as ordinary requests. Site replication service accounts and bucket-replication targets that already hold the replication permissions are unaffected. Inherited from upstream. | | `SN-2026-009` | [`58735ee38`](https://github.com/pgsty/silo/commit/58735ee38) and [`229fe2b3c`](https://github.com/pgsty/silo/commit/229fe2b3c) ([PR #73](https://github.com/pgsty/silo/pull/73)) | Admin `SetUserStatus` and `SetGroupStatus` | Yes; authenticated admin API | Status changes were authorized against `admin:EnableUser` / `admin:EnableGroup` regardless of the requested status, so a principal allowed only to enable could also disable, and vice versa. | Enable and disable now require the action matching the target status. Policies that grant only one of the pair lose the other operation; `admin:*` and the built-in `consoleAdmin` policy are unaffected. Inherited from upstream. | | `SN-2026-010` | [PR #104](https://github.com/pgsty/silo/pull/104) ([`75a6734e4`](https://github.com/pgsty/silo/commit/75a6734e4) through [`d2d47a41f`](https://github.com/pgsty/silo/commit/d2d47a41f), [#58](https://github.com/pgsty/silo/issues/58)) | `DeleteObject` and `DeleteObjects` with an explicit `versionId` | Yes; authenticated S3 API | Explicit version deletes were authorized as `s3:DeleteObject` with only a deny check on `s3:DeleteObjectVersion`, diverging from AWS. | Explicit version deletes now require `s3:DeleteObjectVersion`, as on AWS. **Two policy effects:** principals granted only `s3:DeleteObject` can no longer delete specific versions, and a policy that relied on `Deny s3:DeleteObject` to block permanent deletes must also deny `s3:DeleteObjectVersion`, because `Allow s3:*` now permits explicit version deletes. Replication targets keep the `s3:ReplicateDelete` contract. Inherited from upstream. | +| `SN-2026-011` | [`123325430`](https://github.com/pgsty/silo/commit/1233254309b15571f101b2b26d531951ceaeef1e) | SigV4 signed-header coverage; `x-amz-copy-source` dispatch to `CopyObject` / `UploadPartCopy` | Yes; a party holding only a presigned PUT URL, or any signed PUT, needs no credentials of its own | SigV4 verification only checked that each named signed header was present and never inspected the `x-amz-*` headers that actually arrived (the meta-header check covered only `X-Amz-Meta-` and ran only on the presigned path), while the router dispatches any PUT carrying `x-amz-copy-source` to `CopyObjectHandler`. An unsigned `x-amz-copy-source` therefore turned a one-object write grant into a server-side copy of any object the signing key can read, executed as the signer; both the presigned and Authorization-header paths were affected, and where the destination bucket allows anonymous `GetObject` the copied private bytes become readable unauthenticated. | Any unsigned `x-amz-*` request header is now refused with `AccessDenied` on both paths, matching AWS S3 (AWS returns `403`; Silo returns `400 AccessDenied`, otherwise identical). Membership in the signed-headers list is required, so a header whose first value is empty cannot slip through. `X-Amz-Content-Sha256` remains accepted unsigned (payload hash, taken from the query for presigned requests and bound into the string-to-sign for signed ones); the internal `X-Amz-Signature-Age` scratch header is exempt so repeated verification stays idempotent; `PutObjectTagging` now injects its body-derived `X-Amz-Tagging` header after signature verification. Every AWS SDK, `minio-go`, and `mc` already signs its `x-amz-*` headers, so legitimate clients need no change. Inherited unchanged from upstream `minio/minio`; every earlier release is affected. Reported by Oren Yomtov; a CVE has been requested. | ## Dependency security updates