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.

derived aws emits ExposedToInternet

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'topic_policy': None} HasPolicy {'topic': None}

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 typeTopic
target typeAnonymousIdentity
source?topic
target<AnonymousIdentity>
permissionssns:Publish
conditionsresource_policy
state logicACTIVE 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.
move · open · esc close