Review TLS enforcement for S3 writes

Require HTTPS for S3 writes to protect upload data in transit.

Description

Without a TLS requirement for writes such as uploads, an S3 bucket may accept plaintext HTTP requests from authorized clients. Upload data can then be exposed on the network.

Use aws:SecureTransport in AWS::S3::BucketPolicy to explicitly deny insecure requests. Adding a statement that allows HTTPS does not block HTTP requests permitted by another policy.

Potential impact

  • Plaintext upload data can be intercepted or altered on the network.
  • The configuration may fail an organization’s encryption-in-transit requirements.

Remediation

  • Add an explicit Deny for requests with aws:SecureTransport: false for the actions and resources that need protection.
  • Check that applications and deployment scripts use HTTPS endpoints.
  • Network condition information can be omitted in AWS service-to-service calls. Review necessary service-principal exceptions and test that integrations still work.

Examples

These are bucket-policy excerpts. Supply a valid, unique bucket name through BucketName. The first example’s public-read policy needs a separate public-access review and can be rejected when Block Public Access applies.

Before

yaml
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref BucketName
  BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref S3Bucket
      PolicyDocument:
        Statement:
          - Sid: PublicReadForGetBucketObjects
            Effect: Allow
            Principal: "*"
            Action: s3:GetObject
            Resource: !Sub arn:aws:s3:::${S3Bucket}/*

This statement grants public reads only; it provides neither write permission nor HTTPS enforcement. If another policy allows writes, this statement contains no condition denying HTTP writes.

After

yaml
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref BucketName
  BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref S3Bucket
      PolicyDocument:
        Statement:
          - Sid: EnsureSSL
            Effect: Deny
            Principal: "*"
            Action: s3:PutObject
            Condition:
              Bool:
                aws:SecureTransport: false
            Resource: !Sub arn:aws:s3:::${S3Bucket}/*

HTTP s3:PutObject requests to objects are denied. Upload permission is still required separately, as is TLS enforcement for other actions. The first example’s public-read grant is also removed.

References