Skip to main content
cd ../config-traps
risk/register/wildcard-dns-records-hide-subdomain-takeover-risk.html
DNS Resiliencehigh severityDNS / Route53

Wildcard DNS Records Hide Subdomain Takeover Risk

Overview

When a wildcard record answers takeover scanners' non-existent-label probe, they abort enumeration for the whole zone, so pre-existing dangling CNAMEs to deprovisioned S3, Heroku, or Front Door endpoints stay unflagged. Attackers instead mine certificate transparency logs, claim the orphaned third-party slug, and serve phishing content trusted by cookies, CSP, and SSO redirect rules.

At a glance

Unsafe setting
Wildcard A record combined with unaudited CNAMEs pointing at third-party PaaS endpoints
Failure trigger
Takeover scanner sees wildcard resolve and abandons subdomain enumeration entirely
Blast radius
Attacker claims deprovisioned CNAME target, serving trusted-domain phishing pages that pass cookie, CSP, and SSO checks.
Recommended control
Enumerate via crt.sh, cross-check zone CNAMEs against live provider APIs, terminate wildcards at own LB with fail-closed 404

Fix commands and configuration

aws route53 list-resource-record-sets --hosted-zone-id Z123ABC | jq '.ResourceRecordSets[] | select(.Type=="CNAME")'

The Trap

A wildcard record such as *.domain.com, added as an A record pointing at a load balancer or CDN, is meant to catch mistyped or dynamically provisioned subdomains. Subdomain takeover tooling (tko-subs, Sub404-style scanners, and most commercial ASM crawlers) uses a standard heuristic: query a random non-existent label against the zone, and if it resolves, assume the entire domain is wildcarded and skip further subdomain enumeration to avoid false positives. That heuristic is the trap.

The Default State

Platform teams add the wildcard once, usually for a multi-tenant SaaS front door, and never revisit it. Meanwhile specific CNAME records already exist elsewhere in the same hosted zone, created months earlier for marketing microsites, staging apps, or partner integrations, pointing at third-party endpoints such as an S3 bucket website endpoint, a Heroku app, or an Azure Front Door hostname. DNS exact-match resolution always overrides the wildcard for those specific labels, so blog.domain.com or partner.domain.com still resolves to whatever the CNAME target says, even after that cloud resource has been deleted.

The Blast Radius

Internal scans and external bug bounty tooling see the wildcard hit, conclude the zone is uniformly wildcarded, and abandon enumeration entirely. The dangling CNAME to the deleted S3 bucket or Heroku app is never flagged. An attacker skips DNS brute-forcing altogether, pulls every historical hostname for domain.com from crt.sh certificate transparency logs, finds partner.domain.com pointing at an unclaimed Heroku slug, registers that slug, and serves arbitrary HTML under the company’s own apex domain. Cookies scoped to domain.com, CSP allow-lists, and SSO redirect whitelists all trust the hostname, so the attacker inherits session context and can run credential-harvesting pages that pass every domain-based trust check the browser enforces.

The Lead Mechanic Fix

Stop relying on wildcard-detection heuristics for takeover scanning. Enumerate via certificate transparency instead: pull every issued hostname with a crt.sh query against the domain, then cross-reference each one against the live zone export with aws route53 list-resource-record-sets --hosted-zone-id Z123ABC | jq '.ResourceRecordSets[] | select(.Type=="CNAME")'. For every CNAME target, resolve it directly against the third-party provider’s API, not just DNS, to confirm the resource is still claimed. Fail CI on any target returning NXDOMAIN, a provider-specific “no such app” page, or an unclaimed bucket response. Never point a wildcard directly at a third-party PaaS CNAME; terminate wildcard traffic at your own load balancer with a default 404 vhost, and require unmapped tenant lookups to fail closed rather than silently resolving.