azure-vnet-dns-dangling-takeover
A CNAME or alias DNS record (in a public zone) pointing to a deprovisioned Azure resource enables subdomain takeover: an attacker can claim the target resource and inherit DNS resolution for the dangling name.
where
DNS zone record type is CNAME, ALIAS, or A (with azure-specific alias target)
the record target (CNAME value / alias target resource ID) resolves to a resource that no longer exists in ARM inventory
the target resource type is one known to be claimable by external parties (Azure Blob, App Service, Traffic Manager, Azure CDN, Azure Front Door, Static Web App, API Management, etc.)
emit
| source type | PublicEndpoint |
|---|---|
| target type | AnonymousIdentity |
| source | <DNS zone / dangling record (modeled as PublicEndpoint — the public FQDN is the internet-facing surface)> |
| target | <AnonymousIdentity> |
| state logic | ACTIVE when the dangling record target is confirmed deprovisioned (resource not found in ARM inventory) AND the resource type is known to be claimable (see false_positive_note). POTENTIAL when the target resource is not confirmed in ARM inventory but may simply be in a different subscription not collected (collection gap). |
Narrative
DNS record {record.name} in zone {source.name} is a dangling CNAME/alias pointing to a deprovisioned resource ({targetFqdn}). An external party can claim that resource and resolve {record.name} to attacker-controlled infrastructure (subdomain takeover).
Raw rule rules/derived/azure/vnet.yaml
id: azure-vnet-dns-dangling-takeover
emits: ExposedToInternet
description: 'A CNAME or alias DNS record (in a public zone) pointing to a deprovisioned Azure resource
enables subdomain takeover: an attacker can claim the target resource and inherit DNS resolution for
the dangling name.'
where:
- DNS zone record type is CNAME, ALIAS, or A (with azure-specific alias target)
- the record target (CNAME value / alias target resource ID) resolves to a resource that no longer exists
in ARM inventory
- the target resource type is one known to be claimable by external parties (Azure Blob, App Service,
Traffic Manager, Azure CDN, Azure Front Door, Static Web App, API Management, etc.)
emit:
source_type: PublicEndpoint
target_type: AnonymousIdentity
source: "<DNS zone / dangling record (modeled as PublicEndpoint \u2014 the public FQDN is the internet-facing\
\ surface)>"
target: <AnonymousIdentity>
permissions: []
state_logic: ACTIVE when the dangling record target is confirmed deprovisioned (resource not found in
ARM inventory) AND the resource type is known to be claimable (see false_positive_note). POTENTIAL
when the target resource is not confirmed in ARM inventory but may simply be in a different subscription
not collected (collection gap).
derived_from:
- <DNS record ARM record>
- <ARM inventory cross-reference (resource not found)>
false_positive_note: "Only claimable resource types yield a real takeover surface. Blob storage endpoint\
\ (<account>.blob.core.windows.net), App Service (<name>.azurewebsites.net), Azure CDN (<profile>.azureedge.net),\
\ Front Door (<name>.azurefd.net), Traffic Manager (<name>.trafficmanager.net), Static Web Apps (<name>.azurestaticapps.net)\
\ are confirmed claimable. Azure IP ranges / managed IP resources (Microsoft.Network/publicIPAddresses\
\ owned by the subscription) that are merely deallocated but still in the subscription are NOT claimable\
\ externally \u2014 do not emit. Confirm the target resource does NOT exist in collected ARM inventory\
\ (across all subscriptions in scope) before emitting ACTIVE; downgrade to POTENTIAL if the subscription\
\ is not in collection scope."
narrative: DNS record {record.name} in zone {source.name} is a dangling CNAME/alias pointing to a deprovisioned
resource ({targetFqdn}). An external party can claim that resource and resolve {record.name} to attacker-controlled
infrastructure (subdomain takeover).