DEV Community

Bala Paranj
Bala Paranj

Posted on

Three S3 risks AWS Trusted Advisor can't see

✓ Human-authored analysis; AI used for formatting and proofreading.

"Trusted Advisor says all our S3 buckets are green. Our HIPAA assessment is next month. Are we safe?"

Trusted Advisor is a useful baseline. It checks whether buckets have public access and whether logging is enabled. But it operates on a narrow threat model: "Is this bucket public right now?" Three categories of S3 risk are invisible to it.

Blind spot 1: Incomplete observation data (CTL.S3.INCOMPLETE.001)

Before Trusted Advisor can check a bucket, it needs to read the bucket policy and ACL. What happens if the IAM role running the check lacks s3:GetBucketPolicy permission? Or if the bucket policy explicitly denies the scanner's principal?

Trusted Advisor reports nothing. The bucket doesn't appear in findings because the check couldn't execute. No error or warning. Silence.

Stave treats missing data as a finding, not a pass. The CTL.S3.INCOMPLETE.001 control fires when policy or ACL data is absent from the observation snapshot:

stave evaluate --snapshot observations/snap.json --profile hipaa
Enter fullscreen mode Exit fullscreen mode
── LOW ──

  [FAIL] INCOMPLETE.001 — low
  Finding: Bucket policy data missing from snapshot — safety cannot be proven
  Remediation: Re-run the observation collector with s3:GetBucketPolicy,
  s3:GetBucketAcl, and s3:GetBucketPolicyStatus permissions
Enter fullscreen mode Exit fullscreen mode

Absence of evidence is not evidence of absence. If you cannot read the policy, you cannot prove the bucket is safe.

Blind spot 2: Latent public exposure behind PAB (CTL.S3.PUBLIC.005)

A bucket can have a policy that grants s3:GetObject to Principal: "*" and still appear private if Block Public Access (PAB) is enabled. PAB overrides the public policy at the API layer. Trusted Advisor sees "not public" and reports green.

But PAB is a single toggle. One API call s3api put-public-access-block with all flags set to false and the bucket is instantly public. The underlying public policy is latent, waiting to activate.

Stave's CTL.S3.PUBLIC.005 detects this latent exposure:

── MEDIUM ──

  [FAIL] PUBLIC.005 — medium
  Finding: Public read policy masked only by Public Access Block —
  removing PAB would immediately expose the bucket
  Remediation: Remove the underlying public-granting policy statement
  so the bucket does not depend solely on PAB for protection
Enter fullscreen mode Exit fullscreen mode

AWS Config rule changes, Terraform drift, and well-intentioned "fix the CORS issue" tickets have all disabled PAB on production buckets. If the underlying policy is already public, the exposure is instant.

Blind spot 3: ACL escalation (CTL.S3.ACL.ESCALATION.001)

S3 ACLs have a permission that most engineers have never heard of: WRITE_ACP. This permission lets the grantee modify the ACL itself. If AllUsers has WRITE_ACP, any anonymous user can grant themselves FULL_CONTROL with read, write, delete, and further ACL modification.

Trusted Advisor checks for public READ and WRITE. It does not check for WRITE_ACP or READ_ACP, because these are not direct data access permissions. They are escalation paths.

Stave's CTL.S3.ACL.ESCALATION.001 catches it:

── HIGH ──

  [FAIL] ACL.ESCALATION.001 — high
  Finding: Bucket ACL grants WRITE_ACP to AllUsers — any anonymous user
  can modify the ACL to grant themselves FULL_CONTROL
  Remediation: Remove WRITE_ACP grants and enable S3 Public Access Block
  with BlockPublicAcls set to true
Enter fullscreen mode Exit fullscreen mode

Trusted Advisor answers: "Is this bucket public right now?" That is a useful but incomplete question. For HIPAA compliance, you also need to answer: "Can I prove this bucket's state?" (incomplete data), "Would this bucket become public with one config change?" (latent exposure), and "Can anyone escalate their own permissions?" (ACL escalation). These three blind spots require a tool that models threat paths, not just current state.

Top comments (0)