Skip to content

v0.8.17 — third-round audit closeout (5 follow-up items on v0.8.16) + migration hatch

Choose a tag to compare

@masumi-ryugo masumi-ryugo released this 06 Jun 15:22
· 82 commits to main since this release

Third-round audit closeout. A follow-up Codex CLI + Claude
Code review of v0.8.16 caught 5 residual items (2 MED + 3 LOW).
No CRIT / HIGH after the prior two cycles. This is the version
to target for the Reddit launch
— three full multi-agent audit
cycles have closed every CRIT / HIGH / MED finding from the
pre-release review.

Published to crates.io as s4-server@0.8.17, s4-codec@0.8.17,
s4-config@0.8.17, s4-codec-py@0.8.17. Install via
cargo install s4-server (CPU build).

What's new since v0.8.16

Fixed (#160-#162)

  • #160 G-1 — F-5 presigned-URL 501 is now unconditional.
    The v0.8.16 check ran AFTER let gate = gate?;, so
    deployments without --sigv4a-credentials had
    ?X-Amz-Algorithm=AWS4-ECDSA-P256-SHA256 URLs silently fall
    through to the SigV4 path (which doesn't understand SigV4a
    query auth either). The presigned-detect call now runs
    before the gate guard, so every deployment emits the
    deterministic 501.
  • #161 G-2 — reserved-name guard extended to 8 adjacent
    per-object endpoints: get_object_acl, put_object_acl,
    get_object_attributes, get_object_tagging,
    put_object_tagging, delete_object_tagging,
    restore_object, and upload_part_copy (both source +
    destination). The v0.8.16 F-13 fix only covered GET / HEAD /
    DELETE — a curious client could still
    GetObjectAcl(<key>.s4index) or
    PutObjectAcl(<key>.s4index, public-read) to bypass the
    read-reject via the backend's public-URL path. New shared
    helper S4Service::check_not_reserved_key(...) +
    ReservedKeyMode enum so every site uses the same code; the
    three pre-existing F-13 sites + the M-1 PUT / Copy /
    CreateMultipart sites refactor through the same helper.
  • #162 G-3post_magic_entropy_high short-sample guard
    is now reachable. The v0.8.16 F-12 check inside the helper
    defaulted to false for <= 48-byte samples but the upstream
    MIN_SAMPLE_BYTES = 128 short-circuit in pick_from_sample
    filtered every such sample before it could reach F-12. The
    magic-byte arm now runs above the MIN_SAMPLE_BYTES gate, so
    a 40-byte BZh:loglog: user log actually hits the post-magic
    entropy check and gets routed to the default codec
    (compressed) rather than passed through uncompressed. Closes
    the v0.8.15 M-7 motivation that v0.8.16 F-12 thought it had
    closed.

Added (#163-#164)

  • #163 G-4--allow-legacy-reserved-key-reads CLI flag.
    Migration escape hatch for operators upgrading from
    pre-v0.8.15 deployments that may carry legitimate user-owned
    objects whose key ends in .s4index. When set, the
    reserved-name guard does NOT block GET / HEAD / DELETE on
    .s4index keys; writes (PUT / Copy / Create-Multipart /
    tagging-write / ACL-write) stay blocked regardless of the
    flag so an attacker can't inject into the namespace. Default
    false matches v0.8.16 behaviour; boot-time info-log is
    loud when the flag is on so the operator notices the
    migration window is open.
  • #164 G-5docs/orphan-sidecar-recovery.md operator
    recipe for sweeping the orphan <key>.s4index artifacts
    that v0.8.15 H-g left on versioning-Enabled buckets. v0.8.16
    #151 F-7 stopped emitting new orphans by skipping the
    sidecar block on versioned multipart Complete; this recipe
    handles the one-time cleanup of pre-F-7 leftovers. A future
    release may ship a s4 admin sweep-orphan-sidecars
    subcommand that automates the same loop.

Upgrade notes

  • --allow-legacy-reserved-key-reads is the only new
    operator-visible knob since v0.8.16. The cumulative audit
    surface area still totals three opt-ins:
    --trust-x-forwarded-for (v0.8.11 CRIT-4),
    --prefer-columnar-gpu (v0.8.13 #125), and this v0.8.17
    migration hatch.
  • No behavioural breaks since v0.8.16. The G-2 reserved-name
    guard extension closes a leak that wasn't reachable via the
    aws s3 cp happy path anyway.

Tests

438 lib + 45 integration tests green under
RUSTFLAGS=\"-D warnings\"; cargo clippy --workspace --all-targets clean; cargo fmt --all --check clean; MinIO
E2E job (cargo test --workspace --release -- --ignored --test-threads=1) green on CI.

Full per-issue notes: CHANGELOG.md.
Recovery recipe for v0.8.15 orphan sidecars:
docs/orphan-sidecar-recovery.md.