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

As HTTP is a clear-text protocol, it lack 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 intersept 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: "mynoncompliantbucket"

  S3BucketPolicy:
    Type: 'AWS::S3::BucketPolicy'
    Properties:
      Bucket: !Ref S3Bucket
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Deny
            Principal:
              AWS: # Sensitive: only one principal is forced to use https
                - 'arn:aws:iam::123456789123:root'
            Action: "*"
            Resource: arn:aws:s3:::mynoncompliantbuckets6249/*
            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: "mycompliantbucket"

  S3BucketPolicy:
    Type: 'AWS::S3::BucketPolicy'
    Properties:
      Bucket: "mycompliantbucket"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Deny
            Principal:
              AWS: "*" # all principals should use https
            Action: "*" # for any actions
            Resource: arn:aws:s3:::mycompliantbucket/* # for any resources
            Condition:
              Bool:
                "aws:SecureTransport": false

See