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

S3 Bucket Public Access Via Policy

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: S3-014

Ensure that your Amazon S3 buckets are not publicly accessible to the Internet via bucket policies in order to protect against unauthorized access. Allowing unrestricted access through bucket policies gives everyone the ability to list the objects within the bucket (ListBucket), download objects (GetObject), upload/delete objects (PutObject, DeleteObject), view objects permissions (GetBucketAcl), edit objects permissions (PutBucketAcl) and more. Trend Cloud One™ – Conformity strongly recommends using bucket policies to limit the access to a trusted entity, such as an authorized AWS account, instead of providing access to everyone on the Internet.

This rule can help you with the following compliance standards:

  • 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

Granting public access to your Amazon S3 buckets via bucket policies can allow malicious users to view, get, upload, modify, and delete S3 objects, which can lead to data breaches, data loss and unexpected charges on your AWS monthly bill.


Audit

To determine if your Amazon S3 buckets allow public access via bucket policies, perform the following operations:

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 S3 bucket that you want to examine to access the bucket configuration settings.

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

05 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": "web-data-bucket-policy",
	"Version": "2012-10-17",
	"Statement": [
		{
			"Action": [
				"s3:GetObject",
				"s3:PutObject",
				"s3:DeleteObject"
			],
			"Effect": "Allow",
			"Resource": "arn:aws:s3:::cc-production-web-data/*",
			"Principal": "*"
		}
	]
}

06 Repeat steps no. 3 – 5 for each Amazon S3 bucket that you want to examine, available in your AWS cloud account.

Using AWS CLI

01 Run list-buckets command (OSX/Linux/UNIX) using custom query filters to list the names of all Amazon S3 buckets available in your AWS cloud account:

aws s3api list-buckets 
  --query 'Buckets[*].Name'

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

[
	"cc-production-web-data",
	"cc-project5-debug-data"
]

03 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-production-web-data 
  --query Policy 
  --output text

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

{
	"Id": "web-data-bucket-policy",
	"Version": "2012-10-17",
	"Statement": [
		{
			"Action": [
				"s3:GetObject",
				"s3:PutObject",
				"s3:DeleteObject"
			],
			"Effect": "Allow",
			"Resource": "arn:aws:s3:::cc-production-web-data/*",
			"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.

05 Repeat steps no. 3 and 4 for each Amazon S3 bucket that you want to examine, available within your AWS cloud account.

Remediation / Resolution

To deny public access to your Amazon S3 buckets using bucket policies, perform the following operations:

Using AWS CloudFormation

01 CloudFormation template (JSON):

{
	"AWSTemplateFormatVersion": "2010-09-09",
	"Description": "S3 Bucket Public Access Via Policy",
	"Resources": {
		"S3Bucket": {
			"Type": "AWS::S3::Bucket",
			"Properties": {
				"BucketName": "cc-production-web-data"
			}
		},
		"S3BucketPolicy": {
			"Type": "AWS::S3::BucketPolicy",
			"UpdateReplacePolicy": "Delete",
			"Properties": {
				"Bucket": "cc-production-web-data",
				"PolicyDocument": {
					"Version": "2012-10-17",
					"Statement": [
						{
							"Effect": "Allow",
							"Principal": {
								"AWS": "*"
								"AWS": "arn:aws:iam::123456789012:root"
							},
							"Action": "s3:*",
							"Resource": "arn:aws:s3:::cc-production-web-data/*"
						}
					]
				}
			}
		}
	}
}

02 CloudFormation template (YAML):

AWSTemplateFormatVersion: '2010-09-09'
	Description: S3 Bucket Public Access Via Policy
	Resources:
	S3Bucket:
		Type: AWS::S3::Bucket
		Properties:
		BucketName: cc-production-web-data
	S3BucketPolicy:
		Type: AWS::S3::BucketPolicy
		UpdateReplacePolicy: Delete
		Properties:
		Bucket: cc-production-web-data
		PolicyDocument:
			Version: '2012-10-17'
			Statement:
			- Effect: Allow
				Principal:
					AWS: '*'
					AWS: arn:aws:iam::123456789012:root
				Action: s3:*
				Resource: arn:aws:s3:::cc-production-web-data/*

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" "s3-bucket" {
		bucket = "cc-production-web-data"
	}

	resource "aws_s3_bucket_policy" "s3-bucket-policy" {
		bucket = aws_s3_bucket.s3-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-production-web-data/*"
				}
			]
		})
	}

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 S3 bucket that you want to reconfigure (see Audit section part I to identify the right resource).

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

05 In the Bucket policy section, choose Edit to modify the bucket policy attached to the selected bucket.

06 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::\:root" } or the IAM user, i.e. { "AWS": "arn:aws:iam::\:user/\" } that should have access to the selected Amazon S3 bucket. Choose Save changes to apply the changes.

07 Repeat steps no. 3 – 6 for each publicly accessible Amazon S3 bucket, available in your AWS cloud account.

Using AWS CLI

01 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::\:root" }) or the IAM user (i.e. { "AWS": "arn:aws:iam::\:user/\" }) 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": "web-data-bucket-policy",
	"Version": "2012-10-17",
	"Statement": [
		{
			"Action": [
				"s3:GetObject",
				"s3:PutObject",
				"s3:DeleteObject"
			],
			"Effect": "Allow",
			"Resource": "arn:aws:s3:::cc-production-web-data/*",
			"Principal": {
				"AWS": [
					"arn:aws:iam::123456789012:user/Adam"
				]
			}
		}
	]
}

02 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-production-web-data
    
  • 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-production-web-data 
      --policy file://cc-bucket-policy.json
    

03 Repeat step no. 1 and 2 for each publicly accessible Amazon S3 bucket, available within your AWS cloud account.

References

Publication date May 10, 2016