AWS Security Hub · S3
S3.23: Buckets should log object-level read events
Written and reviewed by Emnode · Last reviewed
What does AWS Security Hub S3.23 check?
S3.23 checks that a multi-Region CloudTrail trail logs S3 object-level read (or all) data events at the account level. It reports FAILED when no trail captures read data events, since reads are off by default.
Why does S3.23 matter?
Read data events are what tell you who accessed which object — the single most important signal in a data-exfiltration investigation. Without them you can see that a bucket exists and was reachable but never which objects an attacker actually pulled. It is the read-side sibling of S3.22's write logging.
How do I fix S3.23?
- Audit your account for a multi-Region trail logging read or all S3 data events.
- Add a read (or all-events) S3 data-event selector to the trail.
- Scope read logging to buckets holding sensitive data with advanced selectors to keep the bill in check.
- Verify read events are being delivered.
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.23 a false positive?
Read logging is separate from write logging — satisfying S3.22 does not satisfy S3.23, and read events are usually the higher-volume, costlier half, so scope them deliberately.
More S3 controls
- 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.9 No S3 access logs, so reads and writes go unaudited
- 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