Skip to main content
emnode / learn
Compliance Medium severity

AWS Security Hub · S3

S3.9: No S3 access logs, so reads and writes go unaudited

Written and reviewed by Emnode · Last reviewed

What does AWS Security Hub S3.9 check?

S3.9 checks whether server access logging is enabled on a bucket. It reports FAILED when a bucket has no logging configuration directing request records to a target log bucket.

Why does S3.9 matter?

Without access logs there is no record of who read or wrote which object, so a data-exfiltration event leaves no trail to reconstruct. In the Capital One breach the attacker's requests were captured in server access logs the whole time — the difference between a 48-hour forensic timeline and three months of guessing comes down to whether logging was on.

How do I fix S3.9?

  1. Stand up a central log-archive bucket and grant the S3 log-delivery group write access to it.
  2. Enable logging on each source bucket with put-bucket-logging, pointing at the archive bucket with a per-source prefix.
  3. Add a lifecycle rule on the archive bucket so log storage costs stay predictable.
  4. Confirm records start landing, and bake logging into your provisioning path so new buckets inherit it.

Remediation script · bash

# Enable server access logging on a flagged bucket, pointing at a central archive bucket.
aws s3api put-bucket-logging \
  --bucket fintech-customer-uploads \
  --bucket-logging-status '{"LoggingEnabled":{"TargetBucket":"fintech-s3-access-logs","TargetPrefix":"customer-uploads/"}}'

# Log object-level read and write data events, scoped to the sensitive prefix only,
# on a multi-Region trail (which is what S3.22 and S3.23 require).
aws cloudtrail put-event-selectors \
  --trail-name acme-management-trail \
  --advanced-event-selectors '[{"Name":"Log read+write data events for customer-records","FieldSelectors":[{"Field":"eventCategory","Equals":["Data"]},{"Field":"resources.type","Equals":["AWS::S3::Object"]},{"Field":"resources.ARN","StartsWith":["arn:aws:s3:::acme-customer-records/"]}]}]'

Full walkthrough (console steps, edge cases and verification) in the lesson Enable S3 access and object-level logging.

Is S3.9 a false positive?

Server access logging is not the same as CloudTrail data events; having one does not satisfy the other, and S3.9 specifically wants server access logging.

Part of the learning path See what's happening
  • S3.1 Account-level S3 public access is not fully blocked
  • S3.2 Public S3 buckets expose data to anyone on the internet
  • S3.3 Buckets can be written to by anyone on the internet
  • S3.5 S3 is accepting unencrypted HTTP requests
  • S3.6 Bucket policy grants broad access to other AWS accounts
  • S3.8 Buckets can still be made public; Block Public Access is off
  • S3.10 Versioned buckets should have lifecycle configurations
  • S3.11 Buckets should have event notifications enabled
  • S3.12 ACLs should not be used to manage bucket access
  • S3.13 Buckets have no lifecycle rules and grow forever
  • S3.15 Buckets should have Object Lock enabled
  • S3.17 Buckets should be encrypted at rest with KMS keys