For AI agents: A markdown version of this page is available at https://docs.datadoghq.com/security/code_security/iac_security/iac_rules/cloudformation-aws-s3-bucket-cloudtrail-logging-disabled.md. A documentation index is available at /llms.txt.
This product is not supported for your selected Datadog site. ().

Metadata

Id: cloudformation-aws-s3-bucket-cloudtrail-logging-disabled

Provider: AWS

Platform: CloudFormation

Severity: Medium

Category: Observability

Learn More

Description

S3 buckets that receive CloudTrail log deliveries should have S3 server access logging enabled so access to log files and object-level operations are recorded for auditing and incident investigation. Without access logs, unauthorized reads, writes, or deletions of delivered logs may go undetected.

This rule looks for AWS::S3::Bucket resources referenced by an AWS::S3::BucketPolicy where PolicyDocument.Statement[].Principal.Service == "cloudtrail.amazonaws.com". For those buckets, Properties.LoggingConfiguration must be defined. Resources missing LoggingConfiguration will be flagged. Set LoggingConfiguration.DestinationBucketName (and optionally LogFilePrefix) to a dedicated logging bucket to collect access logs.

Secure CloudFormation example:

MyCloudTrailBucket:
  Type: AWS::S3::Bucket
  Properties:
    BucketName: my-cloudtrail-bucket
    LoggingConfiguration:
      DestinationBucketName: my-logging-bucket
      LogFilePrefix: access-logs/

Compliant Code Examples

AWSTemplateFormatVersion: "2010-09-09"
Description: A sample template
Resources:
  mybucket:
    Type: "AWS::S3::Bucket"
    DeletionPolicy: Retain
    Properties:
      ReplicationConfiguration:
        Role:
          Fn::GetAtt:
            - WorkItemBucketBackupRole
            - Arn
        Rules:
          - Destination:
              Bucket:
                Fn::Join:
                  - ""
                  - - "arn:aws:s3:::"
                    - "Fn::Join":
                        - "-"
                        - - Ref: "AWS::Region"
                          - Ref: "AWS::StackName"
                          - replicationbucket
              StorageClass: STANDARD
            Id: Backup
            Prefix: ""
            Status: Enabled
      VersioningConfiguration:
        Status: Enabled
      LoggingConfiguration:
        DestinationBucketName: LoggingBucket
        LogFilePrefix: loga/
  WorkItemBucketBackupRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - "sts:AssumeRole"
            Effect: Allow
            Principal:
              Service:
                - s3.amazonaws.com
  SampleBucketPolicy:
    Type: 'AWS::S3::BucketPolicy'
    Properties:
      Bucket:
        Ref: mybucket
      PolicyDocument:
        Statement:
          - Action:
              - 's3:GetObject'
            Effect: Allow
            Resource:
              'Fn::Join':
                - ''
                - - 'arn:aws:s3:::'
                  - Ref: DOC-EXAMPLE-BUCKET
                  - /*
            Principal:
              Service: 'cloudtrail.amazonaws.com'
            Condition:
              StringLike:
                'aws:Referer':
                  - 'http://www.example.com/*'
                  - 'http://example.net/*'

Non-Compliant Code Examples

AWSTemplateFormatVersion: "2010-09-09"
Description: A sample template
Resources:
  mybucketVulnerable:
    Type: "AWS::S3::Bucket"
    DeletionPolicy: Retain
    Properties:
      ReplicationConfiguration:
        Role:
          Fn::GetAtt:
            - WorkItemBucketBackupRole
            - Arn
        Rules:
          - Destination:
              Bucket:
                Fn::Join:
                  - ""
                  - - "arn:aws:s3:::"
                    - Fn::Join:
                        - "-"
                        - - Ref: "AWS::Region"
                          - Ref: "AWS::StackName"
                          - replicationbucket
              StorageClass: STANDARD
            Id: Backup
            Prefix: ""
            Status: Enabled
      VersioningConfiguration:
        Status: Enabled
  WorkItemBucketBackupRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - "sts:AssumeRole"
            Effect: Allow
            Principal:
              Service:
                - s3.amazonaws.com
  sampleBucketPolicy:
    Type: 'AWS::S3::BucketPolicy'
    Properties:
      Bucket:
        Ref: mybucketVulnerable
      PolicyDocument:
        Statement:
          - Action:
              - 's3:GetObject'
            Effect: Allow
            Resource:
              Fn::Join:
                - ''
                - - 'arn:aws:s3:::'
                  - Ref: DOC-EXAMPLE-BUCKET
                  - /*
            Principal:
              Service: 'cloudtrail.amazonaws.com'
            Condition:
              StringLike:
                'aws:Referer':
                  - 'http://www.example.com/*'
                  - 'http://example.net/*'
Transform: AWS::LanguageExtensions
Resources:
  TrailBucket:
    Type: AWS::S3::Bucket
    Properties: {}

  Fn::ForEach::Policies:
    - PolicyName
    - [Trail]
    - TrailBucketPolicy:
        Type: AWS::S3::BucketPolicy
        Properties:
          Bucket:
            Ref: TrailBucket
          PolicyDocument:
            Statement:
              - Effect: Allow
                Principal:
                  Service: cloudtrail.amazonaws.com
                Action: s3:PutObject
                Resource: "*"