gcp-clouddns-record-write-public
A principal holding dns.changes.create (or an equivalent role such as roles/dns.admin, roles/editor, or roles/owner) at the GCP project scope can submit DNS changesets to any public managed zone in that project, overwriting any resource record set - enabling hostname redirect, DNS-01 TLS certificate acquisition, MX record manipulation, and OAuth redirect URI abuse.
match (effective permission)
where
emit
| source type | Identity |
|---|---|
| target type | DNS |
| source | <principal with effective dns.changes.create> |
| target | <public Cloud DNS managed zone in the project> |
| permissions | dns.changes.create dns.resourceRecordSets.create dns.resourceRecordSets.update dns.resourceRecordSets.delete |
| state logic | ACTIVE when the principal's effective IAM policy at the project (or ancestor) scope includes dns.changes.create and no IAM deny policy or org policy constraint blocks it at any level. dns.changes.create is included in roles/dns.admin, roles/editor, and roles/owner; emit for each such binding resolved to the project scope. CONDITIONAL(iam_permission) when an IAM condition expression (e.g. resource tag condition) is attached to the binding and the condition evaluation result is unknown at collection time. BLOCKED when an IAM deny policy (iam.googleapis.com/deny) contains a deny rule covering dns.changes.create for this principal at any scope. Private zones: emit a separate instance with the same permissions but mark state as CONDITIONAL(network_reachability) — exploitation of a private-zone record mutation requires the attacker to have a foothold inside a VPC authorized for the private zone's privateVisibilityConfig.networks list. The CanModifyConfiguration capability itself is ACTIVE (the permission exists), but exploitation is conditional on network position. |
Narrative
{principal.name} holds dns.changes.create at project {project.name} (via {binding.role}) and can submit DNS changesets to public managed zone {zone.name}. This allows creating or overwriting any resource record set in the zone, enabling redirect of hostnames to attacker-controlled infrastructure (phishing, OAuth redirect abuse), DNS-01 TLS certificate acquisition for any name in the zone via a public CA ACME challenge, or MX record manipulation for email interception. Full session capture after redirect requires the FUTURE network-chains linchpin - emit only this record-mutation FACT here.
Raw rule rules/derived/gcp/clouddns.yaml
id: gcp-clouddns-record-write-public
emits: CanModifyConfiguration
description: "A principal holding dns.changes.create (or an equivalent role such as roles/dns.admin, roles/editor,\
\ or roles/owner) at the GCP project scope can submit DNS changesets to any public managed zone in that\
\ project, overwriting any resource record set \u2014 enabling hostname redirect, DNS-01 TLS certificate\
\ acquisition, MX record manipulation, and OAuth redirect URI abuse."
match_effective_permission:
action: dns.changes.create
resource_scope: projects/{project}
where:
- Effective permission includes dns.changes.create at the project (or ancestor folder/org) level
- The target managed zone has visibility == 'public'
- The binding is not blocked by an IAM deny policy or org policy constraint that restricts dns.changes.create
emit:
source_type: Identity
target_type: DNS
source: <principal with effective dns.changes.create>
target: <public Cloud DNS managed zone in the project>
permissions:
- dns.changes.create
- dns.resourceRecordSets.create
- dns.resourceRecordSets.update
- dns.resourceRecordSets.delete
state_logic: "ACTIVE when the principal's effective IAM policy at the project (or ancestor) scope includes\
\ dns.changes.create and no IAM deny policy or org policy constraint blocks it at any level. dns.changes.create\
\ is included in roles/dns.admin, roles/editor, and roles/owner; emit for each such binding resolved\
\ to the project scope. CONDITIONAL(iam_permission) when an IAM condition expression (e.g. resource\
\ tag condition) is attached to the binding and the condition evaluation result is unknown at collection\
\ time. BLOCKED when an IAM deny policy (iam.googleapis.com/deny) contains a deny rule covering dns.changes.create\
\ for this principal at any scope. Private zones: emit a separate instance with the same permissions\
\ but mark state as CONDITIONAL(network_reachability) \u2014 exploitation of a private-zone record\
\ mutation requires the attacker to have a foothold inside a VPC authorized for the private zone's\
\ privateVisibilityConfig.networks list. The CanModifyConfiguration capability itself is ACTIVE (the\
\ permission exists), but exploitation is conditional on network position."
derived_from:
- '<effective IAM binding: principal -> dns.changes.create (or bundled role) at project scope>'
- '<dns.managedZones.list: zone visibility=public>'
false_positive_note: "dns.changes.create is project-scoped; a single binding grants access to ALL public\
\ 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. roles/dns.reader grants only dns.managedZones.list\
\ and dns.resourceRecordSets.list \u2014 it does NOT include dns.changes.create; a reader cannot mutate\
\ records. IAM conditions attached to the binding (e.g. resource tag conditions restricting to specific\
\ zones) narrow the effective scope \u2014 honor them and downgrade to CONDITIONAL(condition_expression)\
\ when they cannot be evaluated. Private zones require a VPC foothold for exploitation; this is a\
\ network_reachability condition on the exploitation path, not on the permission itself. Emit the\
\ edge for private zones but set CONDITIONAL(network_reachability) rather than ACTIVE to accurately\
\ reflect the exploitation barrier."
narrative: "{principal.name} holds dns.changes.create at project {project.name} (via {binding.role})\
\ and can submit DNS changesets to public managed zone {zone.name}. This allows creating or overwriting\
\ any resource record set in the zone, enabling redirect of hostnames to attacker-controlled infrastructure\
\ (phishing, OAuth redirect abuse), DNS-01 TLS certificate acquisition for any name in the zone via\
\ a public CA ACME challenge, or MX record manipulation for email interception. Full session capture\
\ after redirect requires the FUTURE network-chains linchpin \u2014 emit only this record-mutation\
\ FACT here."