Description

Ensure that no Amazon S3 bucket policy allows anyone (public principal *) to write to or delete from the bucket. A policy is considered to allow public write access when it has an Allow statement for all principals with an action such as s3:PutObject, s3:Put*, s3:DeleteObject, s3:Delete*, s3:* or *, and no condition that limits access to specific accounts, organizations, VPCs or VPC endpoints. Buckets protected by the Restrict public buckets setting of S3 Block Public Access, at account or bucket level, pass.

Rationale

Public write access lets anyone upload, overwrite or delete objects in the bucket. Attackers can plant malware, host phishing or illegal content, corrupt data used by applications or delete the bucket contents, causing outages, legal exposure and unexpected storage costs. Write access should be granted only to trusted principals following least privilege, with S3 Block Public Access enabled at account and bucket level as an additional safeguard. Versioning helps recover from unwanted changes.

Impact

  • Prevents anonymous users from uploading, changing or deleting objects

  • Reduces the risk of data tampering, malware hosting and unexpected costs

  • Turning on Restrict public buckets limits access through a public policy to AWS service principals and authorized users in the bucket owner's account, which also blocks any public read access granted by the policy

  • Applications that write to the bucket without credentials stop working until they are given IAM permissions

Default Value

New buckets have no bucket policy, and all four S3 Block Public Access settings are enabled by default for buckets created since April 2023. Public write access exists only if a policy allowing it was added and Block Public Access was turned off.

Pre-Requisites

  • IAM permissions: s3:ListAllMyBuckets, s3:GetBucketPolicy, s3:PutBucketPolicy, s3:GetBucketPublicAccessBlock, s3:PutBucketPublicAccessBlock and s3:GetAccountPublicAccessBlock

  • A list of the users, roles or services that legitimately need write access to the bucket

  • A copy of the current bucket policy and Block Public Access settings

Remediation

Test Plan

Console:

  1. Sign in to the AWS Management Console at https://console.aws.amazon.com.

  2. Open the Amazon S3 console and select Block Public Access settings for this account. If Block public and cross-account access to buckets and objects through any public bucket or access point policies is On, all buckets pass.

  3. Otherwise, select Buckets, select a bucket and open the Permissions tab.

  4. If the same setting is On under Block public access (bucket settings), the bucket passes.

  5. Otherwise, in the Bucket policy section, check for a statement with "Effect": "Allow", a principal of "*" or {"AWS": "*"}, an action such as s3:PutObject, s3:Put*, s3:DeleteObject, s3:Delete*, s3:* or *, and no restricting condition.

  6. Repeat for each bucket.

  7. If such a statement exists, follow the implementation steps.

CLI:

Show the account-level Block Public Access settings:

aws s3control get-public-access-block --account-id <ACCOUNT_ID>

Show the bucket-level Block Public Access settings:

aws s3api get-public-access-block --bucket <BUCKET_NAME>

Show the bucket policy:

aws s3api get-bucket-policy --bucket <BUCKET_NAME> --query Policy --output text

A bucket fails if RestrictPublicBuckets is not true at either account or bucket level, and its policy has an Allow statement for principal * with a write or delete action (s3:PutObject, s3:Put*, s3:DeleteObject, s3:Delete*, s3:* or *) that is not limited by a condition on specific accounts, organizations, VPCs or VPC endpoints.

Implementation Steps

Console:

  1. Sign in to the AWS Management Console at https://console.aws.amazon.com.

  2. Open the Amazon S3 console, select the bucket found in the Test Plan and open the Permissions tab.

  3. In the Bucket policy section, choose Edit and remove the public write statement, or replace the "*" principal with the specific IAM roles or accounts that need write access. Choose Save changes.

  4. Under Block public access (bucket settings), choose Edit.

  5. Select Block public and cross-account access to buckets and objects through any public bucket or access point policies (and the other settings, unless the bucket must remain public for reads).

  6. Choose Save changes and confirm.

  7. Repeat for each affected bucket.

CLI:

Turn on S3 Block Public Access for the bucket. The command replaces the whole Block Public Access configuration of the bucket, and any setting not included is turned off, so all four settings are given here; set a value to false only if the bucket must keep that kind of public access:

aws s3api put-public-access-block --bucket <BUCKET_NAME> --public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true

Backout Plan

Before making changes, save the current bucket policy and Block Public Access settings:

aws s3api get-bucket-policy --bucket <BUCKET_NAME> --query Policy --output text > bucket-policy-backup.json
aws s3api get-public-access-block --bucket <BUCKET_NAME> --query PublicAccessBlockConfiguration > public-access-block-backup.json

To roll back:

  1. Sign in to the AWS Management Console at https://console.aws.amazon.com.

  2. Open the Amazon S3 console, select the bucket and open the Permissions tab.

  3. Under Block public access (bucket settings), choose Edit, restore the previous settings and choose Save changes.

  4. In the Bucket policy section, choose Edit, paste the saved policy and choose Save changes.

CLI:

aws s3api put-public-access-block --bucket <BUCKET_NAME> --public-access-block-configuration file://public-access-block-backup.json
aws s3api put-bucket-policy --bucket <BUCKET_NAME> --policy file://bucket-policy-backup.json

Note: rolling back allows anyone to write to or delete from the bucket again. Use it only as a temporary measure.

Reference