S3 Bucket is publicly readable Affecting S3 service in AWS


Severity

0.0
high
0
10
Severity Framework
Snyk CCSS
Rule category
General/ Access

Is your environment affected by this misconfiguration?

In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.

Test your applications
Frameworks
CIS-Controls
  • Snyk IDSNYK-CC-00285
  • creditSnyk Research Team

Description

S3 buckets should not be publicly readable. A bucket with a public ACL or bucket policy is exposed to the entire internet if all block public access settings are disabled at the resource and account level. This poses a critical security vulnerability, as any AWS user or anonymous user can access the data in the bucket.

How to fix?

Remove any aws_s3_bucket acl, grant, and/or policy fields that allow public read access. Optionally use an aws_s3_bucket_public_access_block or aws_s3_account_public_access_block.

  • Ensure that the aws_s3_bucket acl field does NOT contain EITHER of the following:
    • "public-read"
    • "public-read-write"
  • Ensure that the grant block does NOT contain BOTH an invalid uri and permissions field:
  • If a bucket policy is defined in the bucket's policy field, ensure the JSON document does NOT contain BOTH an invalid principal, an invalid action, and an invalid effect:
    • Invalid principals:
      • "Principal": { "AWS": "*" }
      • "Principal": "*"
    • Invalid actions:
      • "*"
      • "s3:*"
      • "s3:List*"
      • "s3:Get*"
      • "s3:ListBucket*"
      • "s3:GetObject*"
      • "s3:ListBucket"
      • "s3:ListBucketVersions"
      • "s3:ListBucketMultipartUploads"
      • "s3:GetObject"
      • "s3:GetObjectVersion"
      • "s3:GetObjectTorrent"
    • Invalid effect:
      • "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
  • While a aws_s3_bucket_public_access_block is not required for the bucket, it's highly recommended. Ensure the following aws_s3_bucket_public_access_block fields are all set to true:
    • block_public_acls
    • block_public_policy
    • ignore_public_acls
    • restrict_public_buckets
  • You can enable block public access settings for all buckets in your account by using a aws_s3_account_public_access_block. Ensure the following fields are all set to true:
    • block_public_acls
    • block_public_policy
    • ignore_public_acls
    • restrict_public_buckets

Example Configuration

# Compliant ACL
resource "aws_s3_bucket" "b" {
  acl    = "private"
  # other required fields here
}
# Compliant grant
resource "aws_s3_bucket" "bucket" {
  bucket = "mybucket"
  grant {
    id          = data.aws_canonical_user_id.current_user.id
    type        = "CanonicalUser"
    permissions = ["FULL_CONTROL"]
  }
  # other required fields here
}
# Compliant bucket policy
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
}
# Compliant public access block - single bucket
resource "aws_s3_bucket" "b" {
  # other required fields here
}
resource "aws_s3_bucket_public_access_block" "private" {
  bucket                  = "${aws_s3_bucket.b.id}"
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}
# Compliance public access block - ALL buckets
resource "aws_s3_account_public_access_block" "main" {
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}