gcp-cloudsql-enable-public-ip-exposed

cloudsql.instances.update can enable public IP (ipv4Enabled=true) and add 0.0.0.0/0 to authorizedNetworks, making the instance internet-reachable from any network.

derived gcp emits ExposedToInternet

match

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

{'principal': None} CanModifyConfiguration {'instance': None}

where

node_type(?instance) == RelationalDatabase ?principal holds cloudsql.instances.update permission instance currently has ipv4Enabled=false OR authorizedNetworks does not contain 0.0.0.0/0

emit

source typeRelationalDatabase
target typeAnonymousIdentity
source?instance
target<AnonymousIdentity>
permissionscloudsql.instances.update
conditionsiam_permission service_state
state logicPOTENTIAL when cloudsql.instances.update is confirmed effective and the instance does not currently have both public IP AND 0.0.0.0/0 authorized (the attacker CAN make it exposed by executing the configuration change). Never ACTIVE from this rule; if the instance is already public + 0.0.0.0/0, gcp-cloudsql-public-ip-open-network emits ACTIVE and this rule is suppressed by its where-clause guards.

Narrative

{principal.name} holds cloudsql.instances.update on {instance.name} and can enable public IP (ipv4Enabled=true) and add 0.0.0.0/0 to authorizedNetworks, making the database internet-reachable and exploitable from any network.

Raw rule rules/derived/gcp/cloudsql.yaml

id: gcp-cloudsql-enable-public-ip-exposed
emits: ExposedToInternet
description: cloudsql.instances.update can enable public IP (ipv4Enabled=true) and add 0.0.0.0/0 to authorizedNetworks,
  making the instance internet-reachable from any network.
match:
- - principal: null
  - CanModifyConfiguration
  - instance: null
where:
- node_type(?instance) == RelationalDatabase
- ?principal holds cloudsql.instances.update permission
- instance currently has ipv4Enabled=false OR authorizedNetworks does not contain 0.0.0.0/0
emit:
  source_type: RelationalDatabase
  target_type: AnonymousIdentity
  source: ?instance
  target: <AnonymousIdentity>
  permissions:
  - cloudsql.instances.update
  conditions:
  - iam_permission
  - service_state
  state_logic: POTENTIAL when cloudsql.instances.update is confirmed effective and the instance does not
    currently have both public IP AND 0.0.0.0/0 authorized (the attacker CAN make it exposed by executing
    the configuration change). Never ACTIVE from this rule; if the instance is already public + 0.0.0.0/0,
    gcp-cloudsql-public-ip-open-network emits ACTIVE and this rule is suppressed by its where-clause guards.
  false_positive_note: 'This rule models the CAPABILITY to expose the instance (POTENTIAL), not the current
    state (which gcp-cloudsql-public-ip-open-network handles as ACTIVE). Two rules emit ExposedToInternet
    with different purposes: - gcp-cloudsql-public-ip-open-network: ACTIVE when instance IS already exposed
    (current state) - gcp-cloudsql-enable-public-ip-exposed: POTENTIAL when instance CAN BE exposed (attacker
    capability) This rule''s where-clause ensures it fires only when NOT already exposed, preventing duplicate
    ACTIVE edges and path-scoring inflation. Toggling ipv4Enabled requires instance restart; authorizedNetworks
    changes are immediate. After the change, any internet host can connect to the DB port and attempt
    authentication/exploitation.'
  narrative: '{principal.name} holds cloudsql.instances.update on {instance.name} and can enable public
    IP (ipv4Enabled=true) and add 0.0.0.0/0 to authorizedNetworks, making the database internet-reachable
    and exploitable from any network.'
  derived_from:
  - ?principal CanModifyConfiguration ?instance
  - cloudsql.instances.update permission allows ipConfiguration modification
move · open · esc close