gcp-cloudbuild-pubsub-trigger
A principal with pubsub.topics.publish on a trigger's configured Pub/Sub topic can fire that trigger, potentially executing code as the trigger's SA.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?topic) ==
Topic
node_type(?trigger) == BuildWorker
?principal has effective pubsub.topics.publish on ?topic
?trigger.pubsubConfig.topic == ?topic.native_id
emit
| source type | Identity |
|---|---|
| target type | Compute |
| source | <principal with pubsub.topics.publish on ?topic> |
| target | <Cloud Build trigger node (BuildWorker)> |
| permissions | pubsub.topics.publish |
| conditions | attacker_influenced_definition |
| state logic | CONDITIONAL(attacker_influenced_definition): Pub/Sub publish fires the trigger, which runs the CURRENT build definition. Escalation to CanExecuteAs requires the definition to be attacker-influenced (same condition as gcp-cloudbuild-trigger-run). If the trigger's build spec is attacker-controlled (inlineBuild under attacker control, or already poisoned via trigger update): ACTIVE for CanExecuteAs once cicd-chains processes this CanTrigger + ExecutesAs. If the topic is public (allUsers publish): ExposedToInternet feeds here. |
Narrative
{principal.name} can publish to Pub/Sub topic {topic.name} (pubsub.topics.publish), which fires Cloud Build trigger {trigger.name}; if the trigger's build definition is attacker-influenced, this executes code as the trigger's SA {sa.name}.
Raw rule rules/derived/gcp/cloudbuild.yaml
id: gcp-cloudbuild-pubsub-trigger
emits: CanTrigger
description: A principal with pubsub.topics.publish on a trigger's configured Pub/Sub topic can fire that
trigger, potentially executing code as the trigger's SA.
match:
- - ?principal
- CanTrigger
- ?topic
- - ?topic
- CanTrigger
- ?trigger
where:
- node_type(?topic) == Topic
- node_type(?trigger) == BuildWorker
- ?principal has effective pubsub.topics.publish on ?topic
- ?trigger.pubsubConfig.topic == ?topic.native_id
emit:
source_type: Identity
target_type: Compute
source: <principal with pubsub.topics.publish on ?topic>
target: <Cloud Build trigger node (BuildWorker)>
permissions:
- pubsub.topics.publish
conditions:
- attacker_influenced_definition
state_logic: 'CONDITIONAL(attacker_influenced_definition): Pub/Sub publish fires the trigger, which
runs the CURRENT build definition. Escalation to CanExecuteAs requires the definition to be attacker-influenced
(same condition as gcp-cloudbuild-trigger-run). If the trigger''s build spec is attacker-controlled
(inlineBuild under attacker control, or already poisoned via trigger update): ACTIVE for CanExecuteAs
once cicd-chains processes this CanTrigger + ExecutesAs. If the topic is public (allUsers publish):
ExposedToInternet feeds here.'
confidence: 0.7
derived_from:
- <pubsubConfig.topic field from BuildTrigger>
- <pubsub.topics.publish effective permission>
false_positive_note: "Pub/Sub publish alone is not code execution \u2014 it fires the trigger, which\
\ runs the existing definition. Downgrade to CONDITIONAL unless the build definition is demonstrably\
\ attacker-influenced. Also check whether the trigger has a subscription filter (messageBody filter\
\ conditions) that limit which messages fire the build \u2014 an overly restrictive filter may prevent\
\ arbitrary triggering."
narrative: '{principal.name} can publish to Pub/Sub topic {topic.name} (pubsub.topics.publish), which
fires Cloud Build trigger {trigger.name}; if the trigger''s build definition is attacker-influenced,
this executes code as the trigger''s SA {sa.name}.'