aws-sns-topic-exposed-internet
An SNS topic access policy granting sns:Publish to Principal '*' is internet-accessible - anyone can publish and trigger all subscribers.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?topic) ==
Topic
node_provider(?topic) == aws
node_type(?topic_policy) == ResourcePolicy
?topic_policy has a statement granting sns:Publish (or sns:*) to Principal '*' or Principal {AWS: '*'} with no aws:PrincipalOrgID / aws:SourceAccount / aws:SourceArn condition that restricts to a specific account
emit
| source type | Topic |
|---|---|
| target type | AnonymousIdentity |
| source | ?topic |
| target | <AnonymousIdentity> |
| permissions | sns:Publish |
| conditions | resource_policy |
| state logic | ACTIVE when the topic policy unconditionally grants sns:Publish to Principal '*' (no account/org restricting condition). CONDITIONAL(condition_expression) when the wildcard is scoped by a condition the internet principal might satisfy (e.g. aws:SourceIp to a broad CIDR). BLOCKED when an SCP denying sns:Publish for wildcard principals or aws:PrincipalOrgID conditions eliminate external access. |
Narrative
SNS topic {topic.name} has a resource policy granting sns:Publish to Principal '*', making it reachable from the public internet. Any internet caller can publish messages that fan out to all subscribers.
Raw rule rules/derived/aws/sns.yaml
id: aws-sns-topic-exposed-internet
emits: ExposedToInternet
description: "An SNS topic access policy granting sns:Publish to Principal '*' is internet-accessible\
\ \u2014 anyone can publish and trigger all subscribers."
match:
- - topic_policy: null
- HasPolicy
- topic: null
where:
- node_type(?topic) == Topic
- node_provider(?topic) == aws
- node_type(?topic_policy) == ResourcePolicy
- '?topic_policy has a statement granting sns:Publish (or sns:*) to Principal ''*'' or Principal {AWS:
''*''} with no aws:PrincipalOrgID / aws:SourceAccount / aws:SourceArn condition that restricts to a
specific account'
emit:
source_type: Topic
target_type: AnonymousIdentity
source: ?topic
target: <AnonymousIdentity>
permissions:
- sns:Publish
conditions:
- resource_policy
state_logic: ACTIVE when the topic policy unconditionally grants sns:Publish to Principal '*' (no account/org
restricting condition). CONDITIONAL(condition_expression) when the wildcard is scoped by a condition
the internet principal might satisfy (e.g. aws:SourceIp to a broad CIDR). BLOCKED when an SCP denying
sns:Publish for wildcard principals or aws:PrincipalOrgID conditions eliminate external access.
confidence: 0.92
derived_from:
- ?topic_policy HasPolicy ?topic (sns:Publish to Principal '*')
false_positive_note: "Carefully inspect condition keys. A Principal '*' with aws:PrincipalOrgID is NOT\
\ internet-accessible \u2014 it is org-scoped. aws:SourceAccount restricts to a specific account;\
\ aws:SourceArn restricts to a specific resource. Only emit ExposedToInternet when the grant is genuinely\
\ reachable by an unauthenticated external caller. A wildcard-Principal sns:Subscribe grant (rather\
\ than sns:Publish) is data-exfiltration exposure, not Publish exposure \u2014 emit CanReadData for\
\ the Subscribe case, not ExposedToInternet."
narrative: SNS topic {topic.name} has a resource policy granting sns:Publish to Principal '*', making
it reachable from the public internet. Any internet caller can publish messages that fan out to all
subscribers.