Ensure AWS access logging is enabled on S3 buckets

Error: AWS access logging is not enabled on S3 buckets

Bridgecrew Policy ID: BC_AWS_S3_13
Checkov Check ID: CKV_AWS_18
Severity: LOW

AWS access logging is not enabled on S3 buckets

Description

Access logging provides detailed audit logging for all objects and folders in an S3 bucket.

Fix - Runtime

AWS Console

To change the policy using the AWS Console, follow these steps:

  1. Lo gin to the AWS Management Console at https://console.aws.amazon.com/.
  2. Open the Amazon S3 console.
  3. Navigate to the Bucket name list.
  4. To enable server access logging for a bucket, select the name of the bucket.
  5. Click Properties.
  6. Click Server access logging.
  7. Click Enable Logging.

📘

Notes

  • For the target, select the name of the bucket that you want to receive the log record objects.
  • The target bucket must be in the same Region as the source bucket and must not have a default retention period configuration.
  1. Click Save.

CLI Command

The example below sets the logging policy for MyBucket.
The AWS user [email protected] will have full control over the log files, no one else has any access.

### First, grant S3 permission with put-bucket-acl:
aws s3api put-bucket-acl --bucket MyBucket --grant-write URI=http://acs.amazonaws.com/groups/s3/LogDelivery --grant-read-acp URI=http://acs.amazonaws.com/groups/s3/LogDelivery
    
### Then apply the logging policy:
aws s3api put-bucket-logging --bucket MyBucket --bucket-logging-status file://logging.json

### logging.json is a JSON document in the current folder that contains the logging policy:
{
  "LoggingEnabled": {
    "TargetBucket": "MyBucket",
    "TargetPrefix": "MyBucketLogs/",
    "TargetGrants": [
      {
        "Grantee": {
          "Type": "AmazonCustomerByEmail",
          "EmailAddress": "[email protected]"
        },
        "Permission": "FULL_CONTROL"
      }
    ]
  }
}

Fix - Buildtime

Terraform

  • Resource: aws_s3_bucket
  • Argument: logging. This example uses a dynamic block to enable the feature, the purpose here is to be able to add or not logging details by making a list of 0 or more entries.
resource "aws_s3_bucket" "bucket" {
  acl    = var.s3_bucket_acl
  bucket = var.s3_bucket_name
  policy = var.s3_bucket_policy

  force_destroy = var.s3_bucket_force_destroy
  versioning {
    enabled    = var.versioning
    mfa_delete = var.mfa_delete
  }

+  dynamic "logging" {
+    for_each = var.logging
+    content {
+      target_bucket = logging.value["target_bucket"]
+      target_prefix = "log/${var.s3_bucket_name}"
+    }
+  }
}

Alternatively you could just always define the logging block:

resource "aws_s3_bucket" "bucket" {
  acl    = var.s3_bucket_acl
  bucket = var.s3_bucket_name
  policy = var.s3_bucket_policy

  force_destroy = var.s3_bucket_force_destroy
  versioning {
    enabled    = var.versioning
    mfa_delete = var.mfa_delete
  }

+  logging {
+      target_bucket = var.target_bucket
+      target_prefix = "log/${var.s3_bucket_name}"
+   }
}