S3 Account-Level Block Public Access
Overview
This check verifies that your AWS account has S3 Block Public Access settings enabled at the account level. These settings act as a safety net that prevents buckets from being accidentally made public, regardless of individual bucket settings.
Think of it as a master switch that says "no public access allowed" for your entire AWS account.
Risk
Without account-level public access blocking enabled, S3 buckets in your account could be made publicly accessible through ACLs (Access Control Lists) or bucket policies. This creates serious risks:
- Data leaks: Sensitive files could be downloaded by anyone on the internet
- Data tampering: Unauthorized users could modify or delete your files
- Compliance violations: Publicly exposed data may violate regulations like HIPAA or GDPR
- Malware hosting: Attackers could use your storage for malicious purposes
Remediation Steps
Prerequisites
You need permission to modify S3 account settings. Specifically, you need the s3:PutAccountPublicAccessBlock permission.
AWS Console Method
- Sign in to the AWS Management Console
- Go to S3 (search for "S3" in the search bar)
- In the left sidebar, click Block Public Access settings for this account
- Click Edit
- Check all four boxes:
- Block public access to buckets and objects granted through new access control lists (ACLs)
- Block public access to buckets and objects granted through any access control lists (ACLs)
- Block public access to buckets and objects granted through new public bucket or access point policies
- Block public and cross-account access to buckets and objects through any public bucket or access point policies
- Click Save changes
- Type
confirmin the confirmation dialog and click Confirm
AWS CLI (optional)
Run the following command, replacing <account-id> with your 12-digit AWS account ID:
aws s3control put-public-access-block \
--account-id <account-id> \
--public-access-block-configuration \
BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true \
--region us-east-1
To find your account ID, run:
aws sts get-caller-identity --query Account --output text
You can combine these into a single command:
aws s3control put-public-access-block \
--account-id $(aws sts get-caller-identity --query Account --output text) \
--public-access-block-configuration \
BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true \
--region us-east-1
CloudFormation (optional)
Note: AWS CloudFormation does not have a native resource type for S3 account-level public access block settings. You have two alternatives:
Option 1: Use a Custom Resource with Lambda
This approach uses a Lambda function to call the S3 Control API:
AWSTemplateFormatVersion: '2010-09-09'
Description: Enable S3 Account-Level Block Public Access using Custom Resource
Resources:
S3PublicAccessBlockLambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: S3PublicAccessBlockPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:PutAccountPublicAccessBlock
- s3:GetAccountPublicAccessBlock
Resource: '*'
S3PublicAccessBlockLambda:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.12
Handler: index.handler
Role: !GetAtt S3PublicAccessBlockLambdaRole.Arn
Timeout: 60
Code:
ZipFile: |
import boto3
import cfnresponse
def handler(event, context):
try:
account_id = context.invoked_function_arn.split(':')[4]
s3control = boto3.client('s3control')
if event['RequestType'] in ['Create', 'Update']:
s3control.put_public_access_block(
AccountId=account_id,
PublicAccessBlockConfiguration={
'BlockPublicAcls': True,
'IgnorePublicAcls': True,
'BlockPublicPolicy': True,
'RestrictPublicBuckets': True
}
)
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
except Exception as e:
print(f"Error: {e}")
cfnresponse.send(event, context, cfnresponse.FAILED, {'Error': str(e)})
S3PublicAccessBlockCustomResource:
Type: Custom::S3AccountPublicAccessBlock
Properties:
ServiceToken: !GetAtt S3PublicAccessBlockLambda.Arn
Option 2: Use AWS CLI in a deployment script
If you prefer not to use Custom Resources, run the AWS CLI command as a post-deployment step in your CI/CD pipeline.
Terraform (optional)
Terraform has native support for this setting:
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_account_public_access_block" "account_block" {
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
Deploy with:
terraform init
terraform plan
terraform apply
Verification
After making changes, verify the settings are applied:
In the AWS Console:
- Go to S3 > Block Public Access settings for this account
- Confirm all four settings show as On
CLI verification
aws s3control get-public-access-block \
--account-id $(aws sts get-caller-identity --query Account --output text) \
--region us-east-1
Expected output (all values should be true):
{
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": true,
"IgnorePublicAcls": true,
"BlockPublicPolicy": true,
"RestrictPublicBuckets": true
}
}
Additional Resources
- AWS Documentation: Blocking public access to your Amazon S3 storage
- AWS Blog: Amazon S3 Block Public Access
- Prowler Check Documentation
Notes
- This is a high-severity finding. Account-level public access blocking is considered a security best practice and should be enabled in all AWS accounts.
- Existing public buckets: Enabling these settings will not automatically make existing public buckets private. Review individual buckets that require public access and ensure they are intentionally configured.
- Legitimate public access: If you have buckets that genuinely need public access (e.g., static website hosting), you can configure exceptions at the bucket level while keeping account-level protection enabled. The bucket-level settings can override the "Block" settings but not the "Ignore" or "Restrict" settings.
- CloudFormation limitation: Native CloudFormation support is not available; use the Custom Resource approach shown above or Terraform.