Skip to content

Fix signed payloads, Object Lock and federated copies; secure AMQP - #177

Merged
Vonng merged 7 commits into
mainfrom
codex/release-consolidation-20260911
Sep 11, 2026
Merged

Fix signed payloads, Object Lock and federated copies; secure AMQP#177
Vonng merged 7 commits into
mainfrom
codex/release-consolidation-20260911

Conversation

@Vonng

@Vonng Vonng commented Sep 11, 2026

Copy link
Copy Markdown
Member

Requests could satisfy policy conditions with values different from those verified by SigV4, and ordinary writes or federated copies could lose Object Lock protection. This change aligns authorization and payload verification and preserves the destination state of a federated copy.

  • Reject ambiguous repeated copy-source headers; derive presigned signature age from the signed date; expose only the effective payload hash to policy evaluation.
  • Verify header-only presigned body checksums in the generic authentication path. A real HTTP regression checks that a modified bucket policy is rejected and the original policy remains stored; unsigned payload and query precedence controls remain valid.
  • Apply bucket default retention independently of legal hold, forward legal hold on the typed SDK option, let the destination own default encryption, and return the exact copied version and event identity/size.
  • Select merged Console CRC64NVME + COMPOSITE is silently canonicalised to FULL_OBJECT instead of rejected #50 at 638eefd7aece8492ecf8165a94d031544450e784, alongside the existing merged PGSTY package and client selections.
  • Update rabbitmq/amqp091-go from v1.10.0 to v1.14.0 for GHSA-6c5v-hqjr-5xxp. v1.14.0 also enforces the frame limit before negotiation. A loopback broker regression exercises the real AMQP notification target and proves it rejects an oversized frame header without waiting for the body.

Includes the original authored commit from #172, with the three comment spellings reported by its lint job corrected. The extended Object Lock matrix covers ON/OFF, GOVERNANCE/COMPLIANCE, explicit fractional retention, replica boundaries, metadata replacement and source non-inheritance.

Closes #165, closes #166, closes #167, closes #170, closes #176.

Validation:

  • Focused signing, Object Lock and federation regressions under the race detector passed.
  • Real HTTP presigned bucket-policy tampering fails before this fix and is rejected after it; unmodified requests still succeed.
  • The repository lint command passed with golangci-lint v2.13.1.
  • The complete AMQP/event-target test package passed under the race detector; the new oversized-frame test fails against v1.10.0 and passes against v1.14.0. Regenerated dependency credits are unchanged.
  • The final built SILO server and mcli passed object upload/readback and admin-info checks. Embedded Console login and session creation passed, and all eight loaded assets match Console main 638eefd7aece8492ecf8165a94d031544450e784.
  • All eight checks passed on final head d63c92e: full cmd/internal tests, race, lint/generated files, build/vet and cross compilation, vulnerability analysis, and DCO.
  • Full local cmd testing failed only in five existing DNS-dependent test groups because example.org lookup timed out. The same groups fail identically on unchanged main 93e7ef4; the full final cmd suite passed in GitHub CI without skips.

Independent destination Object Lock configuration validation, cross-deployment replica ordering and remote LastModified (#169) remain separate work. This change does not establish OIDC customer-environment, Linux multi-node upgrade, or published-artifact acceptance.

Aeirx and others added 6 commits September 10, 2026 13:15
…yObject

A cross-deployment CopyObject that requests
`x-amz-object-lock-legal-hold: ON` answered 200 while the destination
carried no hold. The resolved value reached the remote as ordinary user
metadata, `X-Amz-Meta-X-Amz-Object-Lock-Legal-Hold`, so nothing applied it.
Retention requested on the same copy survived, which is what made the loss
easy to miss.

The federation branch passes the resolved metadata map straight to
`Core.PutObject` as `PutObjectOptions.UserMetadata`. minio-go's `Header()`
writes the typed lock fields first, then prefixes every UserMetadata key it
does not recognise with `x-amz-meta-`; `supportedHeaders` covers
`x-amz-object-lock-mode` and `x-amz-object-lock-retain-until-date` but not
`x-amz-object-lock-legal-hold`, and `isAmzHeader` does not match it either.
Retention therefore arrives as real headers and the hold does not. The
high-level `validate()` that would have rejected the key never runs, because
`Core.PutObject` goes straight to the low-level PUT.

Carry the hold on the typed `LegalHold` option and forward a cloned map with
the raw key removed. The clone matters twice: typed fields are written before
the UserMetadata loop, so a leftover raw key would add a bogus `x-amz-meta-`
entry beside the correct header, and the proxy's own response and event
metadata are rebuilt from the resolved values rather than the forwarding map,
which no longer carries the hold.

Retention stays in the map deliberately. It already passes through as a
standard header, and moving it to the typed `RetainUntilDate` field would
format with `time.RFC3339` and truncate a retain-until date to whole seconds.

The new test asserts the wire: the remote must receive
`X-Amz-Object-Lock-Legal-Hold` and never the `x-amz-meta-` spelling, and the
destination version must actually store the hold. It fails without the change
with "legal hold forwarded as user metadata [ON]".

Fixes #166

Signed-off-by: Ayush Sharma <72848455+Aeirx@users.noreply.github.com>
…dation-20260911

Signed-off-by: Feng Ruohang <rh@vonng.com>
Signed-off-by: Feng Ruohang <rh@vonng.com>
Signed-off-by: Feng Ruohang <rh@vonng.com>
Signed-off-by: Feng Ruohang <rh@vonng.com>
@Vonng Vonng changed the title fix: close release security and federated copy correctness gaps Fix signed payloads, Object Lock and federated copies; secure AMQP Sep 11, 2026
Signed-off-by: Feng Ruohang <rh@vonng.com>
@Vonng
Vonng marked this pull request as ready for review September 11, 2026 09:08
@Vonng
Vonng merged commit b32f2d9 into main Sep 11, 2026
8 checks passed
@Vonng
Vonng deleted the codex/release-consolidation-20260911 branch September 11, 2026 09:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment