gcp-clouddns-zone-network-binding-update
A principal holding dns.managedZones.update at the GCP project scope can modify the privateVisibilityConfig.networks list for a private managed zone, expanding which VPC networks can resolve the zone. This enables widening the blast radius of a private-zone DNS poisoning attack by adding attacker-controlled VPC networks to the zone's visibility scope (cross-project lateral movement via shared VPC).
match (effective permission)
where
emit
| source type | Identity |
|---|---|
| target type | DNS |
| source | <principal with effective dns.managedZones.update> |
| target | <private Cloud DNS managed zone in the project> |
| permissions | dns.managedZones.update |
| state logic | ACTIVE when the principal's effective IAM policy at the project (or ancestor) scope includes dns.managedZones.update and no IAM deny policy or org policy constraint blocks it at any level. dns.managedZones.update is included in roles/dns.admin and roles/editor; emit for each such binding resolved to the project scope. CONDITIONAL(iam_permission) when an IAM condition expression is attached to the binding. BLOCKED when an IAM deny policy (iam.googleapis.com/deny) covers dns.managedZones.update for this principal at any scope. Only emit for PRIVATE zones; public zones cannot have their visibility scope modified (visibility is immutable once created). |
Narrative
{principal.name} holds dns.managedZones.update at project {project.name} and can modify the network visibility configuration for private managed zone {zone.name}. This allows expanding or narrowing which VPC networks can resolve the zone by modifying privateVisibilityConfig.networks[]. An attacker can use this to inject the zone into attacker-controlled shared VPC networks or cross-project VPCs, extending the blast radius of any DNS record poisoning to additional VPCs. Combined with dns.changes.create, this enables full DNS hijack of services across network boundaries.
Raw rule rules/derived/gcp/clouddns.yaml
id: gcp-clouddns-zone-network-binding-update
emits: CanModifyConfiguration
description: A principal holding dns.managedZones.update at the GCP project scope can modify the privateVisibilityConfig.networks
list for a private managed zone, expanding which VPC networks can resolve the zone. This enables widening
the blast radius of a private-zone DNS poisoning attack by adding attacker-controlled VPC networks to
the zone's visibility scope (cross-project lateral movement via shared VPC).
match_effective_permission:
action: dns.managedZones.update
resource_scope: projects/{project}
where:
- Effective permission includes dns.managedZones.update at the project (or ancestor folder/org) level
- The target managed zone has visibility == 'private'
- The binding is not blocked by an IAM deny policy or org policy constraint that restricts dns.managedZones.update
emit:
source_type: Identity
target_type: DNS
source: <principal with effective dns.managedZones.update>
target: <private Cloud DNS managed zone in the project>
permissions:
- dns.managedZones.update
state_logic: ACTIVE when the principal's effective IAM policy at the project (or ancestor) scope includes
dns.managedZones.update and no IAM deny policy or org policy constraint blocks it at any level. dns.managedZones.update
is included in roles/dns.admin and roles/editor; emit for each such binding resolved to the project
scope. CONDITIONAL(iam_permission) when an IAM condition expression is attached to the binding. BLOCKED
when an IAM deny policy (iam.googleapis.com/deny) covers dns.managedZones.update for this principal
at any scope. Only emit for PRIVATE zones; public zones cannot have their visibility scope modified
(visibility is immutable once created).
derived_from:
- '<effective IAM binding: principal -> dns.managedZones.update (or bundled role) at project scope>'
- '<dns.managedZones.list: zone visibility=private>'
false_positive_note: dns.managedZones.update is project-scoped; a single binding grants access to all
private managed zones in the project. Emit one CanModifyConfiguration edge per (principal, zone) pair
within the project. Do not emit for projects where the principal has the permission at a parent scope
without verifying that the project is within that scope's hierarchy. Modifying privateVisibilityConfig
affects DNS resolution reachability scope (which VPCs can resolve the zone), not record content. This
is a distinct CanModifyConfiguration vector from dns.changes.create (record content mutation). Emit
both edges if the principal holds both permissions.
narrative: '{principal.name} holds dns.managedZones.update at project {project.name} and can modify
the network visibility configuration for private managed zone {zone.name}. This allows expanding or
narrowing which VPC networks can resolve the zone by modifying privateVisibilityConfig.networks[].
An attacker can use this to inject the zone into attacker-controlled shared VPC networks or cross-project
VPCs, extending the blast radius of any DNS record poisoning to additional VPCs. Combined with dns.changes.create,
this enables full DNS hijack of services across network boundaries.'