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 S3 bucket:

AWSTemplateFormatVersion: 2010-09-09
Resources:
  S3Bucket:
    Type: 'AWS::S3::Bucket' # Sensitive

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

AWSTemplateFormatVersion: 2010-09-09
Resources:
  S3Bucket:
    Type: 'AWS::S3::Bucket' # Sensitive
    Properties:
      BucketName: "example-bucket"

  S3BucketPolicy:
    Type: 'AWS::S3::BucketPolicy'
    Properties:
      Bucket: !Ref S3Bucket
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Deny
            Principal:
              AWS: # Only one principal is forced to use https
                - 'arn:aws:iam::123456789123:root'
            Action: "*"
            Resource:
              - arn:aws:s3:::example-bucket
              - arn:aws:s3:::example-bucket/*
            Condition:
              Bool:
                "aws:SecureTransport": false

Compliant Solution

A secure policy that denies the use of all HTTP requests:

AWSTemplateFormatVersion: 2010-09-09
Resources:
  S3Bucket:
    Type: 'AWS::S3::Bucket' # Compliant
    Properties:
      BucketName: "example-bucket"

  S3BucketPolicy:
    Type: 'AWS::S3::BucketPolicy'
    Properties:

      Bucket: !Ref S3Bucket
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Deny
            Principal:
              AWS: "*" # all principals should use https
            Action: "*" # for any actions
            Resource: # for the bucket and all its objects
              - arn:aws:s3:::example-bucket
              - arn:aws:s3:::example-bucket/*
            Condition:
              Bool:
                "aws:SecureTransport": false

See