By default, S3 buckets can be accessed through HTTP and HTTPs protocols.

As HTTP is a clear-text protocol, it lacks the encryption of transported data, as well as the capability to build an authenticated connection. It means that a malicious actor who is able to intercept traffic from the network can read, modify or corrupt the transported content.

Ask Yourself Whether

There is a risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

It’s recommended to deny all HTTP requests:

Sensitive Code Example

No secure policy is attached to this bucket:

resource "aws_s3_bucket" "example-bucket" { # Sensitive
  bucket = "example-bucket"
}

A policy is defined but forces only HTTPs communication for some users:

resource "aws_s3_bucket" "example-bucket" { # Sensitive
  bucket = "example-bucket"
}

resource "aws_s3_bucket_policy" "example-policy" {
  bucket = "example-bucket"

  policy = jsonencode({
    Version = "2012-10-17"
    Id      = "ExamplePolicy"
    Statement = [
      {
        Sid       = "HTTPSOnly"
        Effect    = "Deny"
        Principal = [
          "arn:aws:iam::123456789123:root"
        ] # Only one principal is forced to use HTTPS
        Action    = "s3:*"
        Resource = [
          aws_s3_bucket.aws_s3_bucket.arn,
          "${aws_s3_bucket.aws_s3_bucket.arn}/*",
        ]
        Condition = {
          Bool = {
            "aws:SecureTransport" = "false"
          }
        }
      },
    ]
  })
}

Compliant Solution

A secure policy that denies all HTTP requests is used:

resource "aws_s3_bucket" "example-bucket" {
  bucket = "example-bucket"
}

resource "aws_s3_bucket_policy" "example-policy" {
  bucket = "example-bucket"

  policy = jsonencode({
    Version = "2012-10-17"
    Id      = "ExamplePolicy"
    Statement = [
      {
        Sid       = "HTTPSOnly"
        Effect    = "Deny"
        Principal = {
          "AWS": "*"
        }
        Action    = "s3:*"
        Resource = [
          aws_s3_bucket.example-bucket.arn,
          "${aws_s3_bucket.example-bucket.arn}/*",
        ]
        Condition = {
          Bool = {
            "aws:SecureTransport" = "false"
          }
        }
      },
    ]
  })
}

See