Use the Conformity Knowledge Base AI to help improve your Cloud Posture

Publicly Accessible CloudTrail Buckets

Trend Cloud One™ – Conformity is a continuous assurance tool that provides peace of mind for your cloud infrastructure, delivering over 1000 automated best practice checks.

Risk Level: Very High (act immediately)
Rule ID: CT-003

Check for any publicly accessible CloudTrail trail log buckets (i.e. target buckets) in order to determine if your AWS cloud account could be at risk.

This rule can help you with the following compliance standards:

  • CISAWSF
  • PCI
  • GDPR
  • APRA
  • MAS
  • NIST4

For further details on compliance standards supported by Conformity, see here.

This rule can help you work with the AWS Well-Architected Framework.

This rule resolution is part of the Conformity Security & Compliance tool for AWS.

Security

Using an overly permissive or insecure set of permissions for your CloudTrail trail buckets could provide malicious users access to your logging data, which can increase exponentially the risk of unauthorized access.

Note: As an example, this conformity rule demonstrates how to identify CloudTrail buckets that allow public access via Access Control Lists (ACLs). Public access can also be granted via bucket policies.


Audit

To determine if your CloudTrail buckets are publicly accessible, perform the following actions:

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon CloudTrail console at https://console.aws.amazon.com/cloudtrail/.

03 In the navigation panel, under CloudTrail, choose Trails.

04 Click on the name of the Amazon CloudTrail trail that you want to examine.

05 In the General details section, choose Edit and copy the name of the associated S3 bucket available in the Trail log bucket name box.

06 Navigate to Amazon S3 console at https://console.aws.amazon.com/s3/.

07 Paste the name of the bucket copied at step no. 5 in the Find buckets by name box and click on the name of the returned S3 bucket to access the bucket configuration settings.

08 Select the Permissions tab from the console menu to access the bucket permissions.

09 In the Access control list (ACL) section, check the Access Control List (ACL) configuration settings available for the grantees named Everyone (public access) and Authenticated users group (anyone with an AWS account). The Everyone (public access) grantee is a predefined group that allows all anonymous users to access your Amazon S3 resources. The Authenticated users group (anyone with an AWS account) grantee allows any authenticated user in AWS including those outside your organization access to your Amazon S3 resources. If either the Everyone (public access) grantee or the Authenticated users group (anyone with an AWS account) grantee has List, Reador Write permissions enabled, i.e. Objects set to List, Write, and/or Bucket ACL set to Read, Write, the S3 bucket associated with the selected Amazon CloudTrail trail is considered publicly accessible.

10 In the Bucket policy section, check the policy document attached to the bucket. If the "Effect" element value is set to "Allow" and the "Principal" element value is set to "*" or {"AWS": "*"}, as shown in the policy example listed below, the selected Amazon S3 bucket is publicly accessible (i.e. accessible to everyone):

{
	"Id": "cc-main-cloudtrail-logs-policy",
	"Version": "2012-10-17",
	"Statement": [
		{
			"Action": [
				"s3:GetObject",
				"s3:PutObject",
				"s3:DeleteObject"
			],
			"Effect": "Allow",
			"Resource": "arn:aws:s3:::cc-main-cloudtrail-logs/*",
			"Principal": "*"
		}
	]
}

11 Repeat steps no. 4 – 10 for each Amazon CloudTrail trail created for your AWS cloud account.

Using AWS CLI

01 Run list-trails command (OSX/Linux/UNIX) with custom query filters to list the names of all the Amazon CloudTrail trails created for your AWS cloud account:

aws cloudtrail list-trails
  --region us-east-1
  --query 'Trails[*].Name'

02 The command output should return an array with the requested CloudTrail trail names:

[
	"cc-main-cloud-trail",
	"cc-project5-api-trail",
	"cc-data-events-trail"
]

03 Run describe-trails command (OSX/Linux/UNIX) using the name of the Amazon CloudTrail trail that you want to examine as the identifier parameter and custom query filters to describe the name of the S3 bucket configured to store logs for the selected trail:

aws cloudtrail describe-trails
  --region us-east-1
  --trail-name-list cc-main-cloud-trail
  --query 'trailList[*].S3BucketName'

04 The command output should return the name of the associated bucket:

[
	"cc-main-cloudtrail-logs"
]

05 Run get-bucket-acl command (OSX/Linux/UNIX) using the name of the associated S3 bucket as the identifier parameter, to describe the Access Control List (ACL) configuration set for the Everyone (public access) grantee, available for the selected bucket:

aws s3api get-bucket-acl
  --bucket cc-main-cloudtrail-logs
  --query 'Grants[?(Grantee.URI)]'

06 The command output should return the ACL configuration available. Pay special attention to any instances of permissions granted to the All Users or Authenticated Users groups:

[
	{
		"Grantee": {
			"Type": "Group",
			"URI": "http://acs.amazonaws.com/groups/global/AllUsers"
		},
		"Permission": "FULL_CONTROL"
	},
	{
		"Grantee": {
			"Type": "Group",
			"URI":
	"http://acs.amazonaws.com/groups/global/AuthenticatedUsers"
		},
		"Permission": "WRITE"
	},
	{
		"Grantee": {
			"Type": "Group",
			"URI": "http://acs.amazonaws.com/groups/global/AllUsers"
		},
		"Permission": "READ"
	},
	{
		"Grantee": {
			"Type": "Group",
			"URI": "http://acs.amazonaws.com/groups/global/AllUsers"
		},
		"Permission": "WRITE"
	}
]

If the get-bucket-acl command output returns "FULL_CONTROL", "WRITE", "READ" or "READ_ACP" for the "Permission" attribute for the All Users or Authenticated Users groups, as shown in the example above, the S3 bucket associated with the selected Amazon CloudTrail trail is publicly accessible.

07 Run get-bucket-policy command (OSX/Linux/UNIX) using the name of the Amazon S3 bucket that you want to examine as the identifier parameter to describe the bucket policy (JSON format) attached to the selected S3 bucket:

aws s3api get-bucket-policy
  --bucket cc-main-cloudtrail-logs
  --query Policy
  --output text

08 The command output should return the requested bucket policy document:

{
	"Id": "cc-main-cloudtrail-logs-policy",
	"Version": "2012-10-17",
	"Statement": [
		{
			"Action": [
				"s3:GetObject",
				"s3:PutObject",
				"s3:DeleteObject"
			],
			"Effect": "Allow",
			"Resource": "arn:aws:s3:::cc-main-cloudtrail-logs/*",
			"Principal": "*"
		}
	]
}

Check the policy document returned by the get-bucket-policy command output. If the "Effect" element value is set to "Allow" and the "Principal" element value is set to "*" or {"AWS": "*"}, as shown in the policy example above, the selected Amazon S3 bucket is publicly accessible.

09 Repeat steps no. 3 – 8 for each Amazon CloudTrail trail created for your AWS cloud account.

Remediation / Resolution

To deny public access to the S3 buckets associated with your Amazon CloudTrail trails, perform the following actions:

Using AWS CloudFormation

01 CloudFormation template (JSON):

{
	"AWSTemplateFormatVersion": "2010-09-09",
	"Parameters": {
		"CloudTrailName": {
			"Type": "String"
		},
		"CloudTrailBucketName": {
			"Type": "String"
		},
		"CloudTrailBucketPrefix": {
			"Type": "String"
		}
	},
	"Resources": {
		"CloudTrailBucket": {
			"Type": "AWS::S3::Bucket",
			"Properties": {
				"BucketName": {
					"Ref": "CloudTrailBucketName"
				},
				"AccessControl": "Private",
				"PublicAccessBlockConfiguration": {
					"BlockPublicAcls": true,
					"IgnorePublicAcls": true,
					"BlockPublicPolicy": true,
					"RestrictPublicBuckets": true
				}
			}
		},
		"CloudTrailBucketPolicy": {
			"Type": "AWS::S3::BucketPolicy",
			"UpdateReplacePolicy": "Delete",
			"Properties": {
				"Bucket": "cc-project5-trail-bucket",
				"PolicyDocument": {
					"Version": "2012-10-17",
					"Statement": [
						{
							"Effect": "Allow",
							"Principal": {
								"AWS": "*"
								"AWS": "arn:aws:iam::123456789012:root"
							},
							"Action": "s3:*",
							"Resource": "arn:aws:s3:::cc-project5-trail-bucket/*"
						}
					]
				}
			}
		},
		"CloudTrail": {
			"Type": "AWS::CloudTrail::Trail",
			"Properties": {
				"TrailName": {
					"Ref": "CloudTrailName"
				},
				"S3BucketName": {
					"Ref": "CloudTrailBucketName"
				},
				"S3KeyPrefix": {
					"Ref": "CloudTrailBucketPrefix"
				},
				"IsLogging": true,
				"IsMultiRegionTrail": true,
				"EventSelectors": [
					{
						"DataResources": [
							{
								"Type": "AWS::S3::Object",
								"Values": [
									"arn:aws:s3"
								]
							}
						],
						"ReadWriteType": "All",
						"IncludeManagementEvents": true
					}
				]
			}
		}
	}
}

02 CloudFormation template (YAML):

AWSTemplateFormatVersion: '2010-09-09'
	Parameters:
	CloudTrailName:
		Type: String
	CloudTrailBucketName:
		Type: String
	CloudTrailBucketPrefix:
		Type: String
	Resources:
	CloudTrailBucket:
		Type: AWS::S3::Bucket
		Properties:
		BucketName: !Ref 'CloudTrailBucketName'
		AccessControl: Private
		PublicAccessBlockConfiguration:
			BlockPublicAcls: true
			IgnorePublicAcls: true
			BlockPublicPolicy: true
			RestrictPublicBuckets: true
	CloudTrailBucketPolicy:
		Type: AWS::S3::BucketPolicy
		UpdateReplacePolicy: Delete
		Properties:
		Bucket: cc-project5-trail-bucket
		PolicyDocument:
			Version: '2012-10-17'
			Statement:
			- Effect: Allow
			Principal:
				AWS: '*'
				AWS: arn:aws:iam::123456789012:root
			Action: s3:*
			Resource: arn:aws:s3:::cc-project5-trail-bucket/*
	CloudTrail:
		Type: AWS::CloudTrail::Trail
		Properties:
		TrailName: !Ref 'CloudTrailName'
		S3BucketName: !Ref 'CloudTrailBucketName'
		S3KeyPrefix: !Ref 'CloudTrailBucketPrefix'
		IsLogging: true
		IsMultiRegionTrail: true
		EventSelectors:
			- DataResources:
				- Type: AWS::S3::Object
				Values:
					- arn:aws:s3
			ReadWriteType: All
			IncludeManagementEvents: true

Using Terraform (AWS Provider)

01 Terraform configuration file (.tf):

terraform {
	required_providers {
		aws = {
			source  = "hashicorp/aws"
			version = "~> 4.0"
		}
	}

	required_version = ">= 0.14.9"
}

provider "aws" {
	profile = "default"
	region  = "us-east-1"
}

resource "aws_s3_bucket" "cloud-trail-bucket" {
	bucket = "cc-project5-trail-bucket"
	acl    = "private"
}

resource "aws_s3_bucket_public_access_block" "s3-block-public-access" {
	bucket                  = aws_s3_bucket.cloud-trail-bucket.id
	block_public_acls       = true
	ignore_public_acls      = true
	block_public_policy     = true
	restrict_public_buckets = true
}

resource "aws_s3_bucket_policy" "cloud-trail-bucket-policy" {
	bucket = aws_s3_bucket.cloud-trail-bucket.id
	policy = jsonencode({
		"Version": "2012-10-17",
		"Statement": [
			{
				"Effect": "Allow",
				"Principal": {
					"AWS": "*"
					"AWS": "arn:aws:iam::123456789012:root"
				},
				"Action": "s3:*",
				"Resource": "arn:aws:s3:::cc-project5-trail-bucket/*"
			}
		]
	})
}

resource "aws_cloudtrail" "aws-cloudtrail-trail" {
	name                  = "cc-project5-api-trail"
	s3_bucket_name        = "cc-project5-trail-bucket"
	s3_key_prefix         = "trail-logs"
	enable_logging        = true
	is_multi_region_trail = true
	event_selector {
		data_resource {
			type   = "AWS::S3::Object"
			values = ["arn:aws:s3"]
		}
		read_write_type           = "All"
		include_management_events = true
	}
}

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon S3 console at https://console.aws.amazon.com/s3/.

03 Click on the name of the associated S3 bucket that you want to reconfigure.

04 Select the Permissions tab from the console menu to access the bucket permissions.

05 In the Access control list (ACL) section, choose Edit to modify the Access Control List (ACL) configuration available for the selected bucket.

06 Under Access control list (ACL), deselect all the permissions listed next to the Everyone (public access) grantee, i.e. List, Write from Objects and Read, Write from Bucket ACL, to deny public (anonymous access) to the selected Amazon S3 bucket. Select I understand the effects of these changes on my objects and buckets checkbox for confirmation, then choose Save changes to apply the changes.

07 In the Bucket policysection, choose Edit to modify the bucket policy attached to the selected bucket.

08 In the Policy editor box, perform one of the following actions based on your requirements:

  1. To disable the public access to the selected S3 bucket, delete the entire policy document listed in the Policy editor box or remove just the policy statement that allows public access, then click Save changes to apply the changes.
  2. To limit the access to a specific AWS account or IAM user, replace the "Principal" element value with the Amazon Resource Name (ARN) of the trusted AWS account, i.e. { "AWS": "arn:aws:iam::<aws-account-id>:root" } or the IAM user, i.e. { "AWS": "arn:aws:iam::<aws-account-id>:user/<user-name>" } that should have access to the selected Amazon S3 bucket. Choose Save changes to apply the changes.

09 To limit the access to a specific AWS account or IAM user, replace the "Principal" element value with the Amazon Resource Name (ARN) of the trusted AWS account, i.e. { "AWS": "arn:aws:iam::<aws-account-id>:root" } or the IAM user, i.e. { "AWS": "arn:aws:iam::<aws-account-id>:user/<user-name>" } that should have access to the selected Amazon S3 bucket. Choose Save changes to apply the changes.

10 Repeat steps no. 3 – 9 for each publicly accessible S3 bucket associated with your CloudTrail trail, available within your AWS cloud account.

Using AWS CLI

01 Run put-bucket-acl command (OSX/Linux/UNIX) using the name of the associated S3 bucket that you want to reconfigure as the identifier parameter, to deny public access to the selected Amazon S3 bucket by removing the permissions set for the Everyone (public access) grantee. The following command request removes all the permissions, i.e. LIST (READ), UPLOAD/DELETE (WRITE), VIEW (READ_ACP), and EDIT (WRITE_ACP), from the Everyone (public access) grantee, for the specified S3 bucket (the command request should not produce an output):

aws s3api put-bucket-acl
  --bucket cc-main-cloudtrail-logs
  --acl private

02 Modify the policy document attached to the Amazon S3 that you want to reconfigure (see Audit section part II to identify the right S3 resource) and replace the "Principal" element value with the Amazon Resource Name (ARN) of the trusted AWS account (i.e. { "AWS": "arn:aws:iam::<aws-account-id>:root" }) or the IAM user (i.e. { "AWS": "arn:aws:iam::<aws-account-id>:user/<user-name>" }) that should have access to the selected Amazon S3 bucket. Skip this step if you want to disable the public access by removing the entire bucket policy or just the required policy statement. Save your policy document to a JSON file named cc-bucket-policy.json. The following bucket policy example allows access only to an authorized IAM user named Adam:

{
	"Id": "cc-main-cloudtrail-logs-policy",
	"Version": "2012-10-17",
	"Statement": [
		{
			"Action": [
				"s3:GetObject",
				"s3:PutObject",
				"s3:DeleteObject"
			],
			"Effect": "Allow",
			"Resource": "arn:aws:s3:::cc-main-cloudtrail-logs/*",
			"Principal": {
				"AWS": [
					"arn:aws:iam::123456789012:role/Administrator"
				]
			}
		}
	]
}

03 To deny public access to your Amazon S3 buckets, execute one of the following commands based on your requirements:

  1. Run delete-bucket-policy command (OSX/Linux/UNIX) to remove the non-compliant bucket policy attached to the specified Amazon S3 bucket in order to disable the public access (the command request should not produce an output):
    aws s3api delete-bucket-policy
      --bucket cc-main-cloudtrail-logs
    
  2. Run put-bucket-policy command (OSX/Linux/UNIX) to replace the non-compliant bucket policy attached to the specified Amazon S3 bucket with the policy created at step no. 1 (if successful, the command request should not produce an output):
    aws s3api put-bucket-policy
      --bucket cc-main-cloudtrail-logs
      --policy file://cc-bucket-policy.json
    

04 Repeat steps 1 - 3 for each publicly accessible S3 bucket associated with your CloudTrail trail, available in your AWS cloud account.

References

Publication date Apr 16, 2016