AWS Security Hub · SNS
SNS.4: An SNS topic policy allows public access
Written and reviewed by Emnode · Last reviewed
What does AWS Security Hub SNS.4 check?
SNS.4 fails when a topic's resource policy grants access to a wildcard `Principal` (`"*"`) without a fixed-value condition that scopes it down. Such a policy makes the topic effectively public.
Why does SNS.4 matter?
A public SNS topic can be read from or written to by the entire internet, letting outsiders inject messages into your pipelines or subscribe to events they should never see. These topics rarely arrive through malice; they come from copied getting-started snippets where the scoping `Condition` got dropped or mangled. They look healthy and deliver perfectly while being wide open, so nobody revisits them.
How do I fix SNS.4?
- Pull every topic's resource policy and look for `"Principal": "*"` without a fixed-value condition.
- Replace the wildcard with scoped access: by account, by `aws:PrincipalOrgID`, or by source service via `aws:SourceArn`.
- Keep the legitimate publishers and subscribers working by matching the policy to who actually needs access.
- Add a guardrail so new topics cannot be created with an unconditioned wildcard principal.
Remediation script · bash
# Close the highest-impact public exposure first: databases.
for db in $(aws rds describe-db-instances \
--query 'DBInstances[?PubliclyAccessible==`true`].DBInstanceIdentifier' --output text); do
aws rds modify-db-instance --db-instance-identifier "$db" \
--no-publicly-accessible --apply-immediately
echo "$db: public access removed"
done
# Ratchet S3 shut at the account level so no bucket can be made public again.
aws s3control put-public-access-block --account-id 123456789012 \
--public-access-block-configuration \
'BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true' Full walkthrough (console steps, edge cases and verification) in the lesson Block public access to AWS resources.
Is SNS.4 a false positive?
A topic that is legitimately cross-account is fine as long as the wildcard principal is narrowed by a fixed-value condition (account, org, or source ARN). The control ignores conditions that do not pin to a fixed value, so a too-loose condition still fails.