Lion Cipher Lab
Audit and block public S3 bucket access (offline, the way AWS evaluates it)
- Cloud Security
- Intermediate
- ~50 min
- Free · no account required
Why it matters
The publicly-exposed S3 bucket is the most famous breach in the cloud era -- voter records, hospital files, defense contractor data, and countless backups have all leaked not because someone broke in, but because a storage bucket was quietly set to allow 'everyone.' Amazon S3 is where organisations park their data, and a single mis-set policy or ACL turns a private store into a URL anyone on the internet can read. The hard part is that 'is this bucket public?' is NOT a simple grep for 'Principal: *': AWS has a precise evaluation -- a policy that names a wildcard Principal but is narrowed by a…
What you'll learn
- reading what actually makes an Amazon S3 bucket PUBLIC: a bucket policy statement with Effect:Allow + a wildcard Principal and no restricting Condition, OR an ACL that grants to the predefined AllUsers or AuthenticatedUsers groups
- understanding the four S3 Block Public Access settings (BlockPublicAcls, IgnorePublicAcls, BlockPublicPolicy, RestrictPublicBuckets) and which of them NEUTRALISES a public ACL versus a public policy
- knowing that effective Block Public Access is the MOST RESTRICTIVE combination of a bucket's own flags and the ACCOUNT-level flags -- which is why flipping the four account flags on protects every current and future bucket at once
- writing a pure standard-library Python auditor (json, sys, glob -- no pip, no network) that reproduces AWS's own 'is this bucket effectively public?' evaluation offline over saved JSON configs
- spotting the FALSE POSITIVE a naive 'Principal:*' grep produces: a wildcard-Principal policy narrowed by a fixed Condition (aws:SourceIp / aws:SourceVpce / aws:SourceArn ...) is evaluated by AWS as NON-public, and condemning it is wrong
- producing a measured before/after: 3 genuinely-public buckets with per-bucket reasons, dropping to 0 public after account-level Block Public Access is enabled -- while the naive grep keeps reporting 5
- mapping each offline step to the exact live-account AWS CLI commands (s3api get-public-access-block / get-bucket-policy / get-bucket-acl to read, s3control put-public-access-block and s3api put-public-access-block to remediate)
- carrying the judgment that Block Public Access is the correct blunt default (default-deny at the account, allowlist the rare real exception) but does NOT fix data already exposed, does NOT cover IAM/role access, pre-signed URLs, or CloudFront OAC, and can break a legitimate static-website or public-dataset bucket
Steps in this lab
- What makes an S3 bucket "public" -- every term, defined once
- How you would read this on a real account -- and why we go offline
- Seed six realistic bucket configs as JSON
- Write the auditor -- AWS's public-access logic, offline
- Measure the BEFORE state (account Block Public Access OFF)
- Remediate at the account -- and measure the AFTER state
- The honest limits -- what Block Public Access does NOT fix
- What you built -- and the distinctness to keep straight