gcp-pubsub-topic-public-publish

allUsers or allAuthenticatedUsers granted pubsub.topics.publish on a topic makes it publicly writable; any internet caller can trigger bound push-subscription consumers via messaging-chains without project credentials.

derived gcp emits ExposedToInternet

match

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

{'match_record': {'resource_type': 'google.pubsub.Topic', 'field': 'iamPolicy.bindings'}, 'where': ['a binding grants pubsub.topics.publish or roles/pubsub.publisher to allUsers OR allAuthenticatedUsers']}

where

node_type(?topic) == Topic

emit

source typeTopic
target typeAnonymousIdentity
source<Pub/Sub topic node>
target<AnonymousIdentity>
conditionsresource_policy
state logicACTIVE when the topic IAM binding unconditionally grants pubsub.topics.publish to allUsers (fully unauthenticated) or allAuthenticatedUsers (any Google account — treat as effectively internet-accessible). No IAM condition can restrict allUsers at the topic level (it is the wildcard principal). CONDITIONAL (resource_policy) when a condition expression on the binding would further scope it (unusual for allUsers but theoretically possible). BLOCKED by an org policy (constraints/iam.allowedPolicyMemberDomains) that prevents allUsers/ allAuthenticatedUsers grants at this project/folder/org.

Narrative

Pub/Sub topic {topic.name} grants pubsub.topics.publish to {member} (public); any internet caller can publish messages to {topic.name}, enabling the Phase-10 trigger chain for any push-subscription consumer without project credentials via messaging-chains.

Raw rule rules/derived/gcp/pubsub.yaml

id: gcp-pubsub-topic-public-publish
emits: ExposedToInternet
description: allUsers or allAuthenticatedUsers granted pubsub.topics.publish on a topic makes it publicly
  writable; any internet caller can trigger bound push-subscription consumers via messaging-chains without
  project credentials.
match:
- match_record:
    resource_type: google.pubsub.Topic
    field: iamPolicy.bindings
  where:
  - a binding grants pubsub.topics.publish or roles/pubsub.publisher to allUsers OR allAuthenticatedUsers
where:
- node_type(?topic) == Topic
emit:
  source_type: Topic
  target_type: AnonymousIdentity
  source: <Pub/Sub topic node>
  target: <AnonymousIdentity>
  permissions: []
  conditions:
  - resource_policy
  state_logic: "ACTIVE when the topic IAM binding unconditionally grants pubsub.topics.publish to allUsers\
    \ (fully unauthenticated) or allAuthenticatedUsers (any Google account \u2014 treat as effectively\
    \ internet-accessible). No IAM condition can restrict allUsers at the topic level (it is the wildcard\
    \ principal). CONDITIONAL (resource_policy) when a condition expression on the binding would further\
    \ scope it (unusual for allUsers but theoretically possible). BLOCKED by an org policy (constraints/iam.allowedPolicyMemberDomains)\
    \ that prevents allUsers/ allAuthenticatedUsers grants at this project/folder/org."
  confidence: 0.97
  derived_from:
  - "pubsub.topics.getIamPolicy[bindings \u2014 allUsers/allAuthenticatedUsers member]"
  false_positive_note: "allUsers is genuinely anonymous (no Google sign-in required); allAuthenticatedUsers\
    \ requires any valid Google account \u2014 an internet attacker with a free Google account qualifies.\
    \ Both are modeled as ExposedToInternet for path scoring. An org policy (constraints/iam.allowedPolicyMemberDomains)\
    \ that excludes these members makes the grant ineffective -> BLOCKED. Only pubsub.topics.publish (or\
    \ a role that includes it) creates the ExposedToInternet fact; a subscribe-only wildcard grant is\
    \ a data-exfil exposure but does not produce ExposedToInternet for the trigger chain (emit separately\
    \ as CanReadData with anonymous source)."
  narrative: Pub/Sub topic {topic.name} grants pubsub.topics.publish to {member} (public); any internet
    caller can publish messages to {topic.name}, enabling the Phase-10 trigger chain for any push-subscription
    consumer without project credentials via messaging-chains.
move · open · esc close