Skip to content

Security: cloud37/s3-encryption-gateway

SECURITY.md

Security Policy

Bucket configuration administration (SEC-47)

Configuration mutations require a scoped bucket_permissions: [manage] grant; object rw and bucket create/delete grants do not imply it. Raw configuration bodies are rejected above 1 MiB before backend contact, while Object Lock retains its stricter 100 KiB parser limit.

Multipart routing state (SEC-46)

When Valkey is configured, every new MPU receives a durable routing record with its creation-time encryption policy. UploadPart, UploadPartCopy, Complete, and Abort use that snapshot. Missing state returns NoSuchUpload before backend or source access; transient store failures return ServiceUnavailable and never downgrade to plaintext. Legacy untracked plaintext migration requires the temporary, warned, default-off setting MPU_ALLOW_UNTRACKED_PLAINTEXT_UPLOADS=true.

Supported Versions

Version Supported
0.11.x (latest) ✅
< 0.11 ❌

We provide security fixes for the current minor release only. Older versions do not receive backports.

Reporting a Vulnerability

Please do not report security vulnerabilities through public GitHub issues.

If you discover a vulnerability in the S3 Encryption Gateway, report it privately via one of these channels:

What to Include

A useful report includes:

  • A description of the vulnerability and its potential impact
  • Steps to reproduce or a minimal proof-of-concept
  • Affected version(s) and configuration
  • Whether you have a suggested fix

What to Expect

Timeline Action
48 hours Acknowledgement of your report
7 days Initial severity assessment and triage
30 days Fix or mitigation for confirmed vulnerabilities
90 days Public disclosure (coordinated with reporter)

We follow responsible disclosure: we will coordinate the publication date with you and credit you in the security advisory unless you prefer to remain anonymous.

Scope

In Scope

  • Encryption correctness: weaknesses in the AES-256-GCM, ChaCha20-Poly1305, or HKDF-SHA256 implementations
  • Key material exposure: any path by which a plaintext DEK or password is logged, leaked over the network, or stored insecurely
  • Authentication bypass: weaknesses in AWS Signature V4 validation, admin bearer-token authentication, or rate-limiting
  • Metadata integrity: ability to tamper with or substitute encryption metadata without detection
  • KMIP/KMS integration: vulnerabilities in the Cosmian KMIP or HSM adapter that could lead to key material exposure
  • Container image: critical CVEs in the published cloud37io/s3-encryption-gateway image
  • Privilege escalation in the admin API

Out of Scope

  • Vulnerabilities in the underlying S3 backend (AWS S3, MinIO, etc.)
  • Denial of service via legitimate high request volume (rate limiting is a configuration concern)
  • Issues requiring physical access to the deployment host
  • Security of the operator's own key material management (e.g., a weak password passed to encryption.password)

Security Design

The S3 Encryption Gateway is designed with the following properties:

  • No plaintext at rest: Objects are encrypted before leaving the gateway process. The S3 backend never sees plaintext data or encryption keys.
  • Per-object keys: Each object receives a unique DEK. Compromise of a single object's ciphertext reveals nothing about other objects.
  • Authenticated encryption: AES-256-GCM and ChaCha20-Poly1305 provide both confidentiality and integrity. Tampered ciphertext is detected and rejected before any plaintext is returned.
  • AAD binding: The encryption algorithm, key version, original size, and content type are cryptographically bound to each ciphertext via Additional Authenticated Data. Metadata substitution attacks are detected.
  • FIPS profile: Build with -tags=fips to restrict all cryptographic operations to FIPS-140 approved algorithms (AES-256-GCM, HKDF-SHA256, PBKDF2-HMAC-SHA256).
  • Key zeroization: Plaintext DEKs and derived keys are zeroed from memory immediately after use.
  • Constant-time comparisons: All security-sensitive byte comparisons use crypto/subtle.
  • Manifest resource validation: Untrusted chunk-manifest resource parameters are checked against the wire-format bounds before arithmetic, allocation, or ciphertext authentication. Invalid metadata fails through the existing opaque S3 error surface without revealing supplied values.

SigV4 signed-payload preflight

Header-authenticated SigV4 requests with a concrete lowercase SHA-256 X-Amz-Content-Sha256 value are hashed before routing, encryption, backend access, cache updates, or multipart state mutation. The gateway streams the

Encrypted MPU reservations use bounded Valkey-server-time leases for ambiguous backend outcomes. Only an identical plaintext claim can reacquire an expired lease; token fencing rejects stale commit, renew, and release operations. body into a mode-0600 temporary file, compares the digest in constant time, and only then publishes the replayable body to downstream handlers. Mismatches are rejected atomically and temporary files are removed on success, failure, cancellation, and downstream return. UNSIGNED-PAYLOAD explicitly declines this integrity check and remains supported; AWS-chunked modes retain their existing V1.0-SEC-41 verification path without double spooling.

For the full security architecture, see docs/SECURITY_AUDIT.md and docs/ENCRYPTION_DESIGN.md.

SigV4 streaming uploads

The gateway accepts only the exact STREAMING-AWS4-HMAC-SHA256-PAYLOAD, STREAMING-AWS4-HMAC-SHA256-PAYLOAD-TRAILER, and STREAMING-UNSIGNED-PAYLOAD-TRAILER modes. Signed modes authenticate every chunk and the terminal chunk. Trailer modes require declared, lowercase, supported checksum trailers and strict framing. Bodies are fully verified into 0600 temporary spools before backend or multipart state mutation; decoded length, line, trailer, and chunk bounds are enforced. Invalid or unknown modes fail closed and internal spool failures return InternalError without revealing signatures, keys, payloads, or trailer values.

Verified payload resource bounds

Verified request bodies are admitted before temporary-file creation and are metered while read. The single-request operation matrix and process-wide aggregate budget prevent authenticated clients from exhausting local disk. Excess single requests receive opaque 413 EntityTooLarge; aggregate pressure receives retryable 503 SlowDown. Metrics expose only current bytes and the bounded rejection reasons request_limit and aggregate_limit.

There aren't any published security advisories