S3 bucket policies should not allow list actions for all IAM principals and public users

Description

S3 bucket policies list actions enable users to enumerate information on an organization’s S3 buckets and objects. Malicious actors may use this information to identify potential targets for hacks. Users should scope list actions only to users and roles that require this information - not all principals.

Remediation Steps

AWS Console

  • Navigate to S3.

  • Select the S3 bucket.

  • Click the Permissions tab.

  • Select Bucket Policy.

  • In the Bucket Policy editor, ensure that list actions are not assigned to all (*) principals.

AWS CLI

  • Ensure that S3 bucket policies created via CLI do not allow list actions for all (*) principals:

    • aws s3api put-bucket-policy --bucket <bucket value> --policy '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":["<account id>"]},"Action":"s3:List*","Resource":"<bucket arn>/*"},{"Effect":"Deny","Principal":"*","Action":"*","Resource":"<bucket arn>/*"}]}'

Terraform

  • If a bucket policy is defined in an aws_s3_bucket policy field, ensure the JSON document does NOT contain BOTH an invalid principal, an invalid action, and an invalid effect:

    • Invalid principals:

      • "*"

      • "AWS": "*"

    • Invalid actions:

      • "*"

      • "s3:List*"

      • "s3:ListJobs"

      • "s3:ListBucket"

      • "s3:ListBucketVersions"

      • "s3:ListMultipartUploadParts"

    • Invalid effect:

      • Allow

  • If a bucket policy as defined as an aws_s3_bucket_policy, ensure the JSON document in the policy field does NOT contain BOTH an invalid principal, an invalid action, and an invalid effect, as listed above

Example Configuration

resource "aws_s3_bucket" "b" {
  bucket = "my-tf-test-bucket"
  # other required fields here
}

resource "aws_s3_bucket_policy" "b" {
  bucket = aws_s3_bucket.b.id

  policy = jsonencode({
    Version = "2012-10-17"
    Id      = "MYBUCKETPOLICY"
    Statement = [
      {
        Sid       = "IPAllow"
        Effect    = "Deny"
        Principal = "*"
        Action    = "s3:*"
        Resource = [
          aws_s3_bucket.b.arn,
          "${aws_s3_bucket.b.arn}/*",
        ]
        Condition = {
          NotIpAddress = {
            "aws:SourceIp" = "8.8.8.8/32"
          }
        }
      },
    ]
  })

  # other required fields here
}