gcp-pubsub-update-subscription-can-modify-configuration

pubsub.subscriptions.update allows changing the push endpoint URL and push SA (oidcToken.serviceAccountEmail) on a subscription, enabling push-endpoint redirect for data exfiltration or push SA swap for credential exposure.

derived gcp emits CanModifyConfiguration

match

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

{'match_effective_permission': {'action': 'pubsub.subscriptions.update', 'resource_type': 'google.pubsub.Subscription'}}

emit

source typeIdentity
target typeQueue
source<principal>
target<Pub/Sub subscription node>
permissionspubsub.subscriptions.update
conditionsiam_permission
state logicACTIVE when effective pubsub.subscriptions.update is granted. Swapping the push SA field additionally requires iam.serviceAccounts.actAs on the new SA — if the principal lacks actAs on the desired SA, the push-SA-swap path is POTENTIAL (role_compatibility gate); the push-endpoint-redirect path remains ACTIVE. BLOCKED by IAM deny policy.

Narrative

{principal.name} can update Pub/Sub subscription {subscription.name} (pubsub.subscriptions.update), redirecting its push endpoint to an attacker- controlled URL (data exfiltration of all messages) or swapping the push SA to deliver a different identity's OIDC token to the endpoint (requires actAs on the new SA).

Raw rule rules/derived/gcp/pubsub.yaml

id: gcp-pubsub-update-subscription-can-modify-configuration
emits: CanModifyConfiguration
description: pubsub.subscriptions.update allows changing the push endpoint URL and push SA (oidcToken.serviceAccountEmail)
  on a subscription, enabling push-endpoint redirect for data exfiltration or push SA swap for credential
  exposure.
match:
- match_effective_permission:
    action: pubsub.subscriptions.update
    resource_type: google.pubsub.Subscription
emit:
  source_type: Identity
  target_type: Queue
  source: <principal>
  target: <Pub/Sub subscription node>
  permissions:
  - pubsub.subscriptions.update
  conditions:
  - iam_permission
  state_logic: "ACTIVE when effective pubsub.subscriptions.update is granted. Swapping the push SA field\
    \ additionally requires iam.serviceAccounts.actAs on the new SA \u2014 if the principal lacks actAs\
    \ on the desired SA, the push-SA-swap path is POTENTIAL (role_compatibility gate); the push-endpoint-redirect\
    \ path remains ACTIVE. BLOCKED by IAM deny policy."
  confidence: 0.9
  derived_from:
  - 'effective-permission: pubsub.subscriptions.update on subscription'
  false_positive_note: "The push endpoint redirect (changing pushConfig.pushEndpoint) requires only pubsub.subscriptions.update\
    \ \u2014 no actAs needed to change the URL. However, changing the oidcToken.serviceAccountEmail to\
    \ an ARBITRARY SA requires iam.serviceAccounts.actAs on that SA; without it, GCP rejects the update.\
    \ Do not conflate the two sub-capabilities: endpoint redirect is ACTIVE with only pubsub.subscriptions.update;\
    \ SA swap is POTENTIAL without actAs. A pull subscription (no pushConfig) offers less interesting\
    \ modification targets \u2014 changing deadLetterPolicy or filter is operationally impactful but does\
    \ not directly yield an attack path; still emit CanModifyConfiguration for analyst awareness."
  narrative: '{principal.name} can update Pub/Sub subscription {subscription.name} (pubsub.subscriptions.update),
    redirecting its push endpoint to an attacker- controlled URL (data exfiltration of all messages) or
    swapping the push SA to deliver a different identity''s OIDC token to the endpoint (requires actAs
    on the new SA).'
move · open · esc close