> ## Content Index
> Fetch the complete content index at: https://secblog.reedcloudsec.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# AWS S3 Bucket Hardening Cheat Sheet
- URL: https://secblog.reedcloudsec.com/aws-s3-bucket-hardening-cheat-sheet/
- Published: 2026-09-08T23:31:13.000Z
- Updated: 2026-09-08T23:31:13.000Z
- Description: A practical checklist for locking down S3 buckets — access control, encryption, versioning, logging, and detection — mapped to the exact CIS Foundations Benchmark controls each one satisfies.
- Author: Marselis A. Reed
- Tags: Cloud Security & Hardening

*A practical checklist for locking down S3 buckets — access, encryption, logging, and the CIS controls each item maps to. Baseline as of September 2026.*

S3 misconfiguration remains one of the most common sources of cloud exposure — not because the controls are exotic, but because defaults drift and new buckets get spun up faster than audits catch up. This is a working checklist, not a compliance document: pull from it, don't treat it as complete for your environment.

## What changed recently

**April 2026:** AWS began disabling SSE-C (server-side encryption with customer-provided keys) by default for all new general-purpose buckets and for existing buckets in accounts with no prior SSE-C usage. If your account has never used SSE-C, this needs no action. If you do rely on it, new buckets will reject SSE-C requests with a 403 until you explicitly re-enable it via `PutBucketEncryption`. AWS's own guidance is to leave it disabled unless you have a specific reason — SSE-S3 or SSE-KMS covers most use cases with far less operational friction, since SSE-C requires the caller to supply the key on every single request.

## Access control

- \[ \] **S3 Block Public Access** enabled at both the bucket level and the account level — CIS AWS Foundations Benchmark v5.0.0 control 2.1.4 (Security Hub `S3.1` / `S3.8`)
- \[ \] **Object Ownership** set to "Bucket owner enforced" (ACLs disabled) — the default for new buckets, and worth confirming on anything older, since it leaves IAM/bucket policy as the only access layer instead of a second, easy-to-miss one
- \[ \] No bucket policy grants `"Principal": "*"` or a wildcard `"Action": "*"` without a tightly scoped condition alongside it
- \[ \] Least-privilege IAM — grant the specific actions a role needs, not `s3:*`
- \[ \] Applications and services use **IAM roles for temporary credentials**, not long-lived access keys hardcoded into an application or stored on an EC2 instance

## Encryption

- \[ \] Server-side encryption confirmed on — SSE-S3 is the default for every bucket; move to SSE-KMS where you need customer-managed key control and a CloudTrail audit trail on key usage
- \[ \] SSE-C left disabled unless there's a specific, documented need (see above)
- \[ \] HTTPS enforced via an `aws:SecureTransport` condition in the bucket policy — CIS 2.1.1 (`S3.5`)

## Versioning & recovery

- \[ \] **S3 Versioning** enabled — the baseline protection against accidental overwrite or delete
- \[ \] **MFA Delete** enabled on any bucket storing something sensitive or irreplaceable — CIS 2.1.2 (`S3.20`)
- \[ \] **S3 Object Lock** (WORM) on logs and anything compliance-critical — a common example is locking down your own CloudTrail log bucket so an attacker with write access can't cover their tracks
- \[ \] Cross-Region Replication for buckets that need redundancy beyond S3's default multi-AZ storage (requires versioning enabled on *both* source and destination)

## Logging & monitoring

- \[ \] **S3 server access logging** enabled
- \[ \] **CloudTrail data events** enabled for object-level Get/Put/Delete — this is what actually tells you *who* touched a specific object, not just that the bucket exists (Security Hub `S3.22` write events / `S3.23` read events)
- \[ \] AWS Config managed rules in place: `s3-bucket-public-read-prohibited`, `s3-bucket-public-write-prohibited`, `s3-bucket-versioning-enabled`, `s3-bucket-logging-enabled`, `s3-bucket-ssl-requests-only`
- \[ \] **IAM Access Analyzer for S3** turned on — it flags any bucket reachable from outside the account, including exposure paths a manual policy review can miss

## Detection

- \[ \] **GuardDuty S3 Protection** enabled — anomaly detection over CloudTrail management and data events specific to S3
- \[ \] **Macie** turned on for any bucket that might hold PII or financial data — automated sensitive-data discovery instead of hoping someone remembers what's in there
- \[ \] **Security Hub CSPM** running the CIS AWS Foundations Benchmark v5.0.0 standard for continuous drift detection across everything above

## A note on the control numbers

The CIS mappings above are for **v5.0.0**, the version AWS Security Hub currently recommends. If your org's compliance tooling still references an older version (v1.2.0, v1.4.0, or v3.0.0), the same underlying checks exist but under different section numbers — for example, "Block Public Access" is 2.1.4 in v5.0.0/v3.0.0 but 2.1.5 in v1.4.0\. Worth confirming which version a given audit report is actually citing before assuming a control number lines up.

## Automating this instead of auditing it by hand

Most of the access-control items above are exactly the kind of thing worth codifying instead of checking manually every quarter. This issue's OSS Spotlight covers **Cloud Custodian**, an open-source policy engine whose own example policy is, fittingly, a five-line YAML file that finds S3 buckets with cross-account access and removes it.

---

**Sources:** [AWS — Security best practices for Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/security-best-practices.html?ref=secblog.reedcloudsec.com) · [AWS — Default SSE-C setting for new buckets](https://aws.amazon.com/about-aws/whats-new/2026/04/s3-default-bucket-security-setting/?ref=secblog.reedcloudsec.com) · [AWS Security Hub — CIS AWS Foundations Benchmark control mapping](https://docs.aws.amazon.com/securityhub/latest/userguide/cis-aws-foundations-benchmark.html?ref=secblog.reedcloudsec.com)