Ensure that SES Identities Are Not Publicly Accessible
Overview
This check verifies that Amazon Simple Email Service (SES) identities do not have resource policies that allow public access. SES identities include verified email addresses and domains that you use to send emails.
A "publicly accessible" identity has a policy with Principal: "*" or overly broad permissions, allowing anyone on the internet to use your identity.
Risk
Severity: High
When an SES identity is publicly accessible, unauthorized parties can:
- Send emails as you: Attackers can send spam or phishing emails that appear to come from your domain, damaging your brand reputation
- Trigger account suspension: AWS may throttle or suspend your SES account due to abuse
- Access identity details: Sensitive configuration information may be exposed
This is a common attack vector for email spoofing and brand impersonation.
Remediation Steps
Prerequisites
You need:
- AWS Console access with permissions to manage SES identities
- Knowledge of which AWS accounts or services legitimately need access to your SES identity
AWS Console Method
- Open the Amazon SES Console
- In the left navigation, click Verified identities
- Select the identity flagged by Prowler
- Scroll down to the Authorization section (or Resource policies tab)
- Review each policy attached to the identity
- For any policy with
"Principal": "*":- Click Edit to modify the policy
- Replace
"*"with specific AWS account ARNs (e.g.,"arn:aws:iam::123456789012:root") - Or click Delete to remove the policy entirely if it is no longer needed
- Click Save changes
AWS CLI (optional)
List your SES identities:
aws sesv2 list-email-identities --region us-east-1
View policies for a specific identity:
aws sesv2 get-email-identity-policies \
--email-identity example.com \
--region us-east-1
Delete a public policy:
aws sesv2 delete-email-identity-policy \
--email-identity example.com \
--policy-name <policy-name> \
--region us-east-1
Create a restricted policy:
First, create a policy file (restricted-policy.json):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSpecificAccount",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": [
"ses:SendEmail",
"ses:SendRawEmail"
],
"Resource": "arn:aws:ses:us-east-1:123456789012:identity/example.com"
}
]
}
Then apply it:
aws sesv2 create-email-identity-policy \
--email-identity example.com \
--policy-name restricted-sender-policy \
--policy file://restricted-policy.json \
--region us-east-1
Replace:
example.comwith your identity (email or domain)123456789012with the AWS account ID that needs access<policy-name>with the name of the policy to delete
CloudFormation (optional)
CloudFormation does not natively support SES identity policies. Use AWS CLI commands or Terraform for infrastructure-as-code management of SES policies.
Alternatively, you can use a CloudFormation Custom Resource with Lambda to manage SES identity policies.
Terraform (optional)
resource "aws_ses_identity_policy" "restricted_policy" {
identity = "example.com"
name = "restricted-sender-policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Sid = "AllowSpecificAccount"
Effect = "Allow"
Principal = { AWS = "arn:aws:iam::123456789012:root" }
Action = ["ses:SendEmail", "ses:SendRawEmail"]
Resource = "arn:aws:ses:us-east-1:123456789012:identity/example.com"
}]
})
}
Replace:
example.comwith your verified identity123456789012with the AWS account ID that needs access
To remove an existing public policy, simply remove or modify the aws_ses_identity_policy resource and run terraform apply.
Verification
After making changes:
- Return to the SES Console and select your identity
- Review the Authorization section
- Confirm that no policies contain
"Principal": "*" - Each policy should reference specific AWS account ARNs
CLI verification
aws sesv2 get-email-identity-policies \
--email-identity example.com \
--region us-east-1 \
--query 'Policies'
Review the output and ensure no policy contains "Principal": "*".
Additional Resources
- Amazon SES Sending Authorization
- SES Identity Policy Anatomy
- SES Identity Authorization Policies
- Prowler Check Documentation
Notes
- Legitimate use cases: Some organizations intentionally allow cross-account access for shared services. Ensure you understand your requirements before removing policies.
- Condition keys: For additional security, consider adding conditions like
aws:SourceAccountoraws:SourceArnto further restrict access. - Multiple identities: If you have many identities, repeat this process for each one flagged by Prowler.
- Sending limits: Restricting access does not affect your SES sending limits or quotas.