aws-s3-public-bucket
S3 bucket with a Principal:* bucket policy allowing s3:GetObject and Block Public Access disabled (RestrictPublicBuckets=false) is readable by any internet client.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?bucket) ==
ObjectStorage
?bucket.provider_type == 'AWS::S3::Bucket'
?policy has a statement: Effect=Allow, Principal=* (or Principal={AWS:*}), Action includes s3:GetObject (or s3:*)
?bucket.properties.PublicAccessBlockConfiguration.RestrictPublicBuckets == false (bucket-level BPA)
account-level BPA RestrictPublicBuckets == false
?policy statement has NO aws:PrincipalOrgID / aws:SourceVpc / aws:PrincipalAccount condition restricting access to authenticated principals
emit
| source type | ObjectStorage |
|---|---|
| target type | AnonymousIdentity |
| source | ?bucket |
| target | <AnonymousIdentity> |
| conditions | resource_policy scp_or_org_policy |
| state logic | ACTIVE when BOTH conditions hold: (1) bucket policy has Principal:* Allow on s3:GetObject with no restricting condition, AND (2) Block Public Access RestrictPublicBuckets=false at both bucket AND account level (or account-level is not evaluated / not collected, default to bucket-level). CONDITIONAL(resource_policy) when BPA status is unknown (not collected) — flag for analyst review. BLOCKED when RestrictPublicBuckets=true at either level (BPA overrides the policy). BLOCKED when an SCP denies s3:GetObject for Principal:*. Do not emit when the Allow statement includes a aws:PrincipalOrgID condition — that restricts to org principals, not the public internet. |
Narrative
{bucket.name} has a bucket policy granting s3:GetObject to Principal:'*' and Block Public Access is disabled - any unauthenticated internet client can read all objects in the bucket.
Raw rule rules/derived/aws/s3.yaml
id: aws-s3-public-bucket
emits: ExposedToInternet
description: S3 bucket with a Principal:* bucket policy allowing s3:GetObject and Block Public Access
disabled (RestrictPublicBuckets=false) is readable by any internet client.
match:
- - bucket: null
- HasPolicy
- policy: null
where:
- node_type(?bucket) == ObjectStorage
- ?bucket.provider_type == 'AWS::S3::Bucket'
- '?policy has a statement: Effect=Allow, Principal=* (or Principal={AWS:*}), Action includes s3:GetObject
(or s3:*)'
- ?bucket.properties.PublicAccessBlockConfiguration.RestrictPublicBuckets == false (bucket-level BPA)
- account-level BPA RestrictPublicBuckets == false
- ?policy statement has NO aws:PrincipalOrgID / aws:SourceVpc / aws:PrincipalAccount condition restricting
access to authenticated principals
emit:
source_type: ObjectStorage
target_type: AnonymousIdentity
source: ?bucket
target: <AnonymousIdentity>
permissions: []
conditions:
- resource_policy
- scp_or_org_policy
state_logic: "ACTIVE when BOTH conditions hold: (1) bucket policy has Principal:* Allow on s3:GetObject\
\ with no restricting condition, AND (2) Block Public Access RestrictPublicBuckets=false at both bucket\
\ AND account level (or account-level is not evaluated / not collected, default to bucket-level).\
\ CONDITIONAL(resource_policy) when BPA status is unknown (not collected) \u2014 flag for analyst\
\ review. BLOCKED when RestrictPublicBuckets=true at either level (BPA overrides the policy). BLOCKED\
\ when an SCP denies s3:GetObject for Principal:*. Do not emit when the Allow statement includes a\
\ aws:PrincipalOrgID condition \u2014 that restricts to org principals, not the public internet."
confidence: min(contributing_confidences) * 0.98
derived_from:
- ?bucket HasPolicy ?policy (GetBucketPolicy + GetBucketPolicyStatus evidence)
- ?bucket.properties.PublicAccessBlockConfiguration.RestrictPublicBuckets == false
false_positive_note: "Block Public Access is the AUTHORITATIVE override \u2014 it takes precedence over\
\ any bucket or object ACL, and (for RestrictPublicBuckets) also over bucket policies. Check BOTH\
\ account-level BPA (via s3control:GetPublicAccessBlock) AND bucket-level BPA (via s3:GetBucketPublicAccessBlock).\
\ A bucket policy with Principal:* BUT with an aws:PrincipalOrgID condition is NOT internet-public\
\ \u2014 only authenticated AWS principals in the org can access it; emit ExposedToTenant instead.\
\ A Principal:* Allow restricted by aws:SourceVpc is private-only (emit PrivateReachability). The\
\ IsPublic flag from GetBucketPolicyStatus is the reliable shortcut when available. Static website\
\ endpoints (GetBucketWebsite) are a separate public exposure vector (see rule aws-s3-static-website-public),\
\ independent of the bucket policy public-access flag. Note: s3:ListBucket (if also public) exposes\
\ object keys \u2014 flag as ContainsResourceReference on the bucket node."
narrative: "{bucket.name} has a bucket policy granting s3:GetObject to Principal:'*' and Block Public\
\ Access is disabled \u2014 any unauthenticated internet client can read all objects in the bucket."