---
title: S3 bucket without SSL in write actions
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > Datadog Security > Code Security > Infrastructure as Code (IaC)
  Security > IaC Security Rules > S3 bucket without SSL in write actions
---

# S3 bucket without SSL in write actions

{% callout %}
# Important note for users on the following Datadog sites: app.ddog-gov.com, us2.ddog-gov.com

{% alert level="danger" %}
This product is not supported for your selected [Datadog site](https://docs.datadoghq.com/getting_started/site.md). ({% placeholder "user-datadog-site-name" /%}).
{% /alert %}

{% /callout %}

## Metadata{% #metadata %}

**Id:** `cloudformation-aws-s3-bucket-without-ssl-in-write-actions` 

**Provider:** AWS

**Platform:** CloudFormation

**Severity:** Medium

**Category:** Encryption

#### Learn More{% #learn-more %}

- [Provider Reference](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html)

### Description{% #description %}

S3 buckets should enforce SSL/TLS for data in transit to prevent unencrypted requests from exposing sensitive data or enabling man-in-the-middle attacks.

Ensure each `AWS::S3::Bucket` has an associated `AWS::S3::BucketPolicy` whose `Properties.PolicyDocument.Statement` enforces `aws:SecureTransport`. For example, use a `Deny` statement that blocks unsafe actions (such as `s3:*` or `s3:PutObject`) when `Condition.Bool["aws:SecureTransport"]` is `false`. Alternatively, use `Allow` statements that only permit those actions when `aws:SecureTransport` is `true`.

Resources missing an `AWS::S3::BucketPolicy`, or with statements that do not include the `Condition.Bool["aws:SecureTransport"]` check (that is, do not deny unsecured requests), will be flagged.

Secure configuration example:

```yaml
MyBucketPolicy:
  Type: AWS::S3::BucketPolicy
  Properties:
    Bucket: !Ref MyBucket
    PolicyDocument:
      Statement:
        - Sid: EnforceSSL
          Effect: Deny
          Principal: "*"
          Action: "s3:*"
          Resource:
            - !Sub "arn:aws:s3:::${MyBucket}"
            - !Sub "arn:aws:s3:::${MyBucket}/*"
          Condition:
            Bool:
              aws:SecureTransport: "false"
```

## Compliant Code Examples{% #compliant-code-examples %}

```yaml
#this code is a correct code for which the query should not find any result
AWSTemplateFormatVersion: 2010-09-09
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: S3Bucket
      AccessControl: PublicRead
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html
    DeletionPolicy: Retain
  BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      PolicyDocument:
        Id: MyPolicy
        Version: 2012-10-17
        Statement:
          - Sid: PublicReadForGetBucketObjects
            Effect: Allow
            Principal: '*'
            Action: 's3:GetObject'
            Resource: !Join
              - ''
              - - 'arn:aws:s3:::'
                - !Ref S3Bucket
                - /*
          - Sid: EnsureSSL
            Effect: Deny
            Principal: '*'
            Action: 's3:PutObject'
            Condition:
              Bool:
                'aws:SecureTransport': false
            Resource: !Join
              - ''
              - - 'arn:aws:s3:::'
                - !Ref S3Bucket
                - /*
      Bucket: !Ref S3Bucket
Outputs:
  WebsiteURL:
    Value: !GetAtt
      - S3Bucket
      - WebsiteURL
    Description: URL for website hosted on S3
  S3BucketSecureURL:
    Value: !Join
      - ''
      - - 'https://'
        - !GetAtt
          - S3Bucket
          - DomainName
    Description: Name of S3 bucket to hold website content
```

```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  S3Bucket2:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: S3Bucket2
      AccessControl: PublicRead
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html
    DeletionPolicy: Retain
  BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      PolicyDocument:
        Id: MyPolicy
        Version: 2012-10-17
        Statement:
          - Sid: EnsureSSL
            Effect: Deny
            Principal: '*'
            Action: 's3:*'
            Condition:
              Bool:
                'aws:SecureTransport': false
            Resource: !Join
              - ''
              - - 'arn:aws:s3:::'
                - !Ref S3Bucket2
                - /*
      Bucket: !Ref S3Bucket2
  S3Bucket3:
    Type: AWS::S3::Bucket
    Properties:
      AccessControl: PublicRead
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html
    DeletionPolicy: Retain
  BucketPolicy2:
    Type: AWS::S3::BucketPolicy
    Properties:
      PolicyDocument:
        Id: MyPolicy2
        Version: 2012-10-17
        Statement:
          - Sid: EnsureSSL
            Effect: Deny
            Principal: '*'
            Action: 's3:*'
            Condition:
              Bool:
                'aws:SecureTransport': false
            Resource: !Join
              - ''
              - - 'arn:aws:s3:::'
                - !Ref S3Bucket3
                - /*
      Bucket: !Ref S3Bucket3
Outputs:
  WebsiteURL:
    Value: !GetAtt
      - S3Bucket2
      - WebsiteURL
    Description: URL for website hosted on S3
  S3BucketSecureURL:
    Value: !Join
      - ''
      - - 'https://'
        - !GetAtt
          - S3Bucket2
          - DomainName
    Description: Name of S3 bucket to hold website content
```

```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  S3Bucket33:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: S3Bucket33
      AccessControl: PublicRead
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html
    DeletionPolicy: Retain
  BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      PolicyDocument:
        Id: MyPolicy
        Version: 2012-10-17
        Statement:
            Effect: Deny
            Principal: '*'
            Action: 's3:*'
            Condition:
              Bool:
                'aws:SecureTransport': false
            Resource: !Join
              - ''
              - - 'arn:aws:s3:::'
                - !Ref S3Bucket3
                - /*
      Bucket: !Ref S3Bucket33
```

## Non-Compliant Code Examples{% #non-compliant-code-examples %}

```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: S3Bucket
      AccessControl: PublicRead
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html
    DeletionPolicy: Retain
  BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      PolicyDocument:
        Id: MyPolicy
        Version: 2012-10-17
        Statement:
          - Sid: PublicReadForGetBucketObjects
            Effect: Allow
            Principal: '*'
            Action: 's3:GetObject'
            Resource: !Join
              - ''
              - - 'arn:aws:s3:::'
                - !Ref S3Bucket
                - /*
      Bucket: !Ref S3Bucket
Outputs:
  WebsiteURL:
    Value: !GetAtt
      - S3Bucket
      - WebsiteURL
    Description: URL for website hosted on S3
  S3BucketSecureURL:
    Value: !Join
      - ''
      - - 'https://'
        - !GetAtt
          - S3Bucket
          - DomainName
    Description: Name of S3 bucket to hold website content
```

```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  S3Bucket2:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: S3Bucket2
      AccessControl: PublicRead
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html
    DeletionPolicy: Retain
  BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      PolicyDocument:
        Id: MyPolicy
        Version: 2012-10-17
        Statement:
          - Sid: EnsureSSL
            Effect: Deny
            Principal: '*'
            Action: 's3:PutObject'
            Condition:
              Bool:
                'aws:SecureTransport': true
            Resource: !Join
              - ''
              - - 'arn:aws:s3:::'
                - !Ref S3Bucket2
                - /*
      Bucket: !Ref S3Bucket2
Outputs:
  WebsiteURL:
    Value: !GetAtt
      - S3Bucket2
      - WebsiteURL
    Description: URL for website hosted on S3
  S3BucketSecureURL:
    Value: !Join
      - ''
      - - 'https://'
        - !GetAtt
          - S3Bucket2
          - DomainName
    Description: Name of S3 bucket to hold website content
```

```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  S3Bucket3:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: S3Bucket3
      AccessControl: PublicRead
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html
    DeletionPolicy: Retain
  S3Bucket4:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: S3Bucket4
      AccessControl: PublicRead
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html
    DeletionPolicy: Retain
  BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      PolicyDocument:
        Id: MyPolicy
        Version: 2012-10-17
        Statement:
          - Sid: EnsureSSL
            Effect: Allow
            Principal: '*'
            Action: 's3:*'
            Condition:
              Bool:
                'aws:SecureTransport': false
            Resource: !Join
              - ''
              - - 'arn:aws:s3:::'
                - !Ref S3Bucket3
                - /*
      Bucket: !Ref S3Bucket3
Outputs:
  WebsiteURL:
    Value: !GetAtt
      - S3Bucket3
      - WebsiteURL
    Description: URL for website hosted on S3
  S3BucketSecureURL:
    Value: !Join
      - ''
      - - 'https://'
        - !GetAtt
          - S3Bucket3
          - DomainName
    Description: Name of S3 bucket to hold website content
```
