- Knowledge Base
- Amazon Web Services
- AWS CloudTrail
- Publicly Accessible CloudTrail Buckets
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.
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:
- 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.
- 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:
- 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
- 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
- AWS Documentation
- How CloudTrail works
- CloudTrail Concepts
- Amazon S3 bucket policy for CloudTrail
- Identity and access management in Amazon S3
- Access control list (ACL) overview
- AWS Command Line Interface (CLI) Documentation
- cloudtrail
- list-trails
- describe-trails
- s3api
- get-bucket-acl
- put-bucket-acl