CVE-2026-33322 |
d24f449e0 |
OIDC STS (AssumeRoleWithWebIdentity, AssumeRoleWithClientGrants) |
Yes |
Closes JWT algorithm confusion by removing HMAC/shared-secret verification and requiring JWKS-backed verifier keys |
Breaking change: providers issuing HS256, HS384, or HS512 tokens for these STS flows must switch to JWKS-backed RSA or ECDSA signing before upgrading. PS256 and EdDSA are not currently supported. |
CVE-2026-33419 |
3b950f8fa |
LDAP STS authentication |
Yes |
Prevents username enumeration by unifying unknown-user and bad-password responses and adds in-memory login throttling |
Unknown users and invalid passwords now both return 400 InvalidParameterValue. Rate limiting is per-node, in-memory, and not currently configurable. Follow-up hardening landed in 18b712d49, 9e10f6d9a, and f44110890. |
CVE-2026-34204 |
56fa63bfd |
Replication metadata handling |
Yes |
Blocks untrusted X-Minio-Replication-* headers from being smuggled into internal replication metadata and leaving objects unreadable |
Upgrade any server that accepts untrusted PutObject or CopyObject requests, which in practice means almost any production server that accepts writes. |
CVE-2026-39414 |
3252d5b7f |
S3 Select oversized record handling |
Yes |
Rejects oversized CSV records and non-simdjson line-delimited JSON records with OverMaxRecordSize instead of buffering them unchecked |
Split oversized JSON lines client-side if you rely on simdjson input paths until the fast path gains the same pre-check. |
| CVE-2026-41145 |
f444b6f37 |
Unsigned-trailer PUT and multipart upload authentication |
Yes |
Closes the query-string authentication bypass in unsigned-trailer streaming requests |
Upgrade if clients can reach object write endpoints using the STREAMING-UNSIGNED-PAYLOAD-TRAILER content-sha256 mode together with query-string SigV4 credentials. |
| CVE-2026-40344 |
efb6e5b00 |
Snowball auto-extract authentication |
Yes |
Verifies request authentication before tar extraction in Snowball unsigned-trailer flows |
Upgrade if you use PutObjectExtract or Snowball uploads. |
| CVE-2026-42600 |
73ac52472 |
Internode ReadMultiple storage-REST endpoint |
Yes (cluster-root JWT required) |
Removes the unused endpoint that allowed path traversal outside configured drive roots |
Upgrade distributed-erasure deployments. Single-node deployments do not register this route. |
SN-2026-002 |
ca7baa670 and follow-ups |
Internode storage-REST and Grid RPC payloads |
Yes (cluster-root / internode JWT required) |
Completes CVE-2026-42600. Its fix removed one endpoint that exercised the gap; the gap itself -- request bodies and grid frames never reaching the validity middleware, and no containment in the storage layer -- remained across three further protocol surfaces. Closes path traversal on both the volume and path axes (including the peer-S3 bucket RPCs, which bypass the storage-REST wrapper entirely), an unrecoverable divide-by-zero that killed a node per RPC frame, metadata that reported truncated shards as intact, and three allocations sized from caller-declared values. |
Upgrade distributed-erasure deployments. Single-node deployments register none of these routes. No S3 API behaviour changes; object keys containing . or .. path segments were already refused at the S3 boundary. |
SN-2026-003 |
silo-pkg v3.11.0 and 2f55347f7 |
S3/IAM bucket-policy condition values |
Yes (policy-dependent) |
Prevents raw request entries that spell condition-key names from shadowing or synthesizing internal condition values; confines s3:signatureAge to verified SigV4 presigned requests; separates query-only list fields from header-backed x-amz-* fields; and stops client request tags from impersonating stored existing-object tags. |
The compatible query form remains for storage class and upload tagging on handlers that consume it; an explicitly present header wins, including an empty header. The historical X-Amz-Tagging Header mapping remains a client-supplied RequestObjectTag source, so use request-tag conditions only on operations that consume tags. Header-only x-amz-* policy keys no longer accept query substitutes. aws:SourceIp was left following the existing forwarding-header trust model; that model is addressed separately in the next row. See Condition value sources and precedence. |
| Not a vulnerability |
fe6dc4780 |
Client source address (aws:SourceIp, audit remotehost, event notification Host) |
N/A -- opt-in hardening |
Adds an enforceable forwarded-header trust boundary, MINIO_API_TRUSTED_PROXIES. Set to a list of addresses or CIDR blocks, forwarded headers are believed only from those peers and forwarding chains are read right-to-left past listed hops -- which also stops the client-supplied left-most entry that an appending proxy (the stock nginx $proxy_add_x_forwarded_for recipe, or HAProxy's added second header line) leaves in place. Set to none, no forwarded header is believed at all. This is the guarantee _MINIO_API_XFF_HEADER=off never provided: it suppresses X-Forwarded-For alone, so X-Real-IP and RFC 7239 Forwarded remain one-line substitutions for anyone that setting was meant to stop. |
No behaviour change for any existing deployment, so there is nothing to do on upgrade unless you want the new boundary. Not assigned a CVE: the default matches upstream, and upstream's own position (maintainer response in discussion #17878, Aug 2023) is that IP-based restrictions are impractical without reliable source-IP visibility. The gap being closed is that this was never written anywhere an operator would find it -- an IpAddress condition is accepted and behaves as though it works. If you use IpAddress or NotIpAddress conditions, note that they were not enforceable before this change, including behind a reverse proxy whose X-Forwarded-For recipe appends rather than overwrites. If you do not, the change affects only the accuracy of client addresses in logs. The new variable is opt-in and inert when unset; _MINIO_API_XFF_HEADER keeps its exact upstream semantics, and upstream's TestXFFDisabled is retained unmodified as the proof. An IpAddress condition remains unenforceable by default against a client with direct network access to the API port -- that is the condition the allowlist exists to fix, not a regression introduced here. When enabling the allowlist: it must name proxies, not the subnet they sit in, because entries are skipped while walking the chain, so a range that also covers clients lets those clients forge. Multi-node deployments must include their own node addresses, since MinIO forwards some requests between nodes and a client can force a hop through the ListObjectsV2 continuation token; prefer the allowlist over none on a cluster for that reason. Loopback is always trusted as a peer so FTP and SFTP keep attributing their sessions. A malformed value stops startup, as does one that names no proxy at all (",") or one whose env:// remote could not be read -- env.Get discards that error and yields an empty string, which would otherwise read as unset. Whitespace-only remains equivalent to unset. The policy is read after MINIO_CONFIG_ENV_FILE is loaded so environment-file deployments are covered; _MINIO_API_XFF_HEADER deliberately keeps upstream's earlier read timing, where a value written into an environment file is ignored. MINIO_IDENTITY_LDAP_STS_TRUSTED_PROXIES now shares the same list parser, but is behaviourally untouched: the extraction is pure code motion, verified identical to the previous implementation across every combination of 37 allowlist values and 21 peer addresses. See Client source address trust. |
SN-2026-004 |
silo-pkg v3.11.0 and 97b7d2804 |
IAM policy evaluation of bucket-level actions |
Yes (policy-dependent) |
Withholds twelve sensitive bucket-level writes from an object-only resource pattern. The IAM matcher appended a trailing slash for bucket-level requests (empty object name), so a resource of arn:aws:s3:::bucket/* matched "bucket/" and authorized bucket-level actions it was never meant to reach -- upstream minio/minio#20449. The bucket-policy evaluation path never had the slash and was already reference-correct. |
This is an authorization tightening; read this row before upgrading if you write your own bucket-scoped policies. Withheld from bucket/* on Allow statements only: PutBucketPolicy, DeleteBucketPolicy, PutBucketObjectLockConfiguration, PutBucketVersioning, PutReplicationConfiguration, PutBucketLifecycle, DeleteBucket, ForceDeleteBucket, PutBucketCors, DeleteBucketCors, PutBucketQOS, PutInventoryConfiguration. Membership was decided by one question -- does reaching this action give the caller something its object-scoped grant does not already give it? -- because the bug only fires when the statement already grants the bucket action, which in practice means s3:*, so the affected principal already holds full object CRUD. Only actions that hand out access to others, defeat a protection aimed at write-holders, act under server credentials, outlive the grant, or destroy the bucket entity qualify. Deliberately not withheld, and asserted by test so re-adding one is a deliberate act: ListBucket, GetBucketLocation and the read/list family, PutBucketTagging, PutBucketEncryption, PutBucketNotification, and CreateBucket -- so mc ls, SDK session setup and ordinary tenant self-service keep working through bucket/*. Breaking those is what got upstream's own full fix reverted. What to change: add the bare bucket ARN (arn:aws:s3:::bucket) alongside arn:aws:s3:::bucket/* in any statement that legitimately grants one of the twelve. Built-in canned policies are unaffected (all use Resource: "*"). Deny statements are untouched, so no bucket lock is ever weakened, and NotResource exclusions keep their full reach. The hardening is monotone by construction rather than by argument: the protected path requires both the bare and the historical "bucket/" form to match, an intersection with the historical decision -- without that, a fixed-width wildcard such as mybucke? would match "mybucket" while never having matched "mybucket/", and the hardening would have granted a write the buggy matcher refused. MINIO_API_LEGACY_BUCKET_RESOURCE_MATCH=on restores the historical behaviour in full; it is read once at startup. Still deferred to a migration-gated release: the read/list family, a startup audit naming affected policies, and a self-explaining denial log. |
SN-2026-005 |
silo-pkg v3.12.0 and eee05a17c |
IAM named-policy and service-account policy writes |
No direct remote exploit; policy-dependent |
Rejects S3, S3 Tables, and KMS ARN namespace prefixes that name no resource, including their historical *arn:... serialization, in both Resource and NotResource. A resource-matching Deny using such a prefix could silently fail to deny, while an Allow with the prefix in NotResource could match far more broadly than intended. The guard applies when creating named policies and when creating or updating service-account session policies. |
This is an authorization tightening for new and updated policies. Existing policies keep loading, matching, importing, and replicating with unchanged runtime behavior, but a policy containing one of these prefixes cannot be submitted unchanged; replace it with the intended concrete resource, or use an explicit wildcard such as arn:aws:s3:::* only when all resources are intended. Enabling the strict path also rejects an admin statement that combines Resource with NotResource, and rejects non-S3 resources on bucket-scoped admin actions. Here “bare ARN prefix” means a namespace with no resource after it (arn:aws:s3:::); it is distinct from the valid “bare bucket ARN” in SN-2026-004 (arn:aws:s3:::bucket). IAM import, site-replication receive paths, stored-policy loading, and STS inline policies remain on the permissive compatibility path in this release. |
SN-2026-006 |
b73581b05 and c4fd97d0b (#82) |
SSE-C reads of zero-byte objects (GetObject, HeadObject, CopyObject source, GetObjectAttributes) |
Yes; requires read access to the object |
Zero-byte SSE-C objects never unsealed the customer-provided key, so a wrong key was accepted with 200 instead of 403, and a copy or new version could be created under a key of the caller's choosing without knowing the current one. |
Wrong keys now fail with 403 AccessDenied as on AWS; correct keys behave as before and no client change is needed. Inherited from upstream; every earlier release is affected. |
SN-2026-007 |
474cd5801, 74c97d005, 21870fa2e (#84) |
GetObjectAttributes on SSE-C objects |
Yes; requires read access to the object |
Attributes of SSE-C objects were returned without authenticating the customer key, and a bare X-Minio-Source-Replication-Request header skipped the check entirely. |
A wrong key returns 403, a replication marker without the key returns 400; replication peers holding s3:ReplicateObject are unaffected. Inherited from upstream. |
SN-2026-008 |
PR #101 (938603458 through 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 and 229fe2b3c (PR #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 (75a6734e4 through d2d47a41f, #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. |