Subdomain takeover: detection and prevention
How dangling CNAME, NS and MX records let others serve content on your subdomains, how to find them in your own zones, and how to stop it happening.
How a takeover happens
Teams point subdomains at hosted services all the time: docs.example.com to a static site host, shop.example.com to an e-commerce platform, assets.example.com to a storage bucket. The DNS record is usually a CNAME to a name the provider assigned, such as example-docs.hosting.example.net. When the service is cancelled, the resource is deleted, but the CNAME often stays.
That leftover record is called dangling DNS. If the provider lets any customer create a resource with the same name, whoever claims it controls what docs.example.com serves. Browsers show your domain in the address bar, and many providers will even issue a valid TLS certificate for it.
Record types that can dangle
| Record | Dangling when | Consequence |
|---|---|---|
| CNAME | Target resource at a cloud or SaaS provider was deleted | Web content and certificates on your subdomain |
| NS delegation | Subdomain delegated to a DNS hosting zone that no longer exists, or to name servers on an expired domain | Full control of all records under that subdomain |
| MX | Points to a mail host on a domain that expired or a service that was cancelled | Mail for that name delivered to someone else |
| A / AAAA | Points to a cloud IP address you released | Whoever gets the IP next receives your traffic |
| CNAME to an expired domain | Target is under a domain nobody renewed | Anyone who registers that domain controls the target |
NS delegations are the most severe case. Control of the delegated zone means control of every record under it, including MX, TXT and verification records, not just a single web page. They are also rarer and easier to audit, because delegations to external name servers are unusual in most zones.
Why it matters
Content on a subdomain inherits trust that belongs to your organisation. Users see login.example.com and assume it is yours; security filters and allowlists that trust *.example.com let it through. The damage depends on what else trusts your domain name.
- Phishing with a genuine domain name and a valid certificate.
- Cookie theft when session cookies are set with
Domain=example.com, which sends them to every subdomain. - CSP and CORS bypass when policies allow
https://*.example.com. - OAuth and redirect abuse when allowed redirect URIs include wildcard subdomains.
- Email abuse through dangling MX or NS records, including receiving password reset mail for addresses on that name.
- Reputation damage when malware or spam is served from your domain and ends up on blocklists.
Scope cookies narrowly
Domain attribute (host-only) unless you really need them on subdomains. That alone removes the most damaging consequence of a takeover.Finding dangling records in your zones
Start from your own authoritative data: zone exports from every DNS provider you use, including zones managed by other teams and by agencies. Scanning only the names you remember misses exactly the records that cause takeovers. Then check each record whose target is outside your control.
- Export all zones and list every CNAME, NS, MX and A/AAAA record.
- For CNAMEs, resolve the target.
NXDOMAINfor the target, or a target under a domain that is not registered, is a strong signal. - For targets at hosting providers, request the subdomain over HTTPS and HTTP and look for the provider's "not found" or "no such site" page.
- For NS delegations, query the delegated name servers directly for the subdomain's SOA;
REFUSEDorSERVFAILsuggests the hosted zone is gone. - For MX and CNAME targets under other domains, check with the WHOIS lookup whether those domains are still registered.
- For A records into cloud ranges, confirm the IP is still assigned to your account.
# where does it point?
dig +short CNAME docs.example.com
example-docs.hosting.example.net.
# does the target still exist?
dig +short example-docs.hosting.example.net A
dig example-docs.hosting.example.net A | grep -E 'status: (NXDOMAIN|NOERROR)'
# what does the subdomain serve?
curl -sS -o /dev/null -w '%{http_code}\n' https://docs.example.com/The DNS Lookup and DNS Lookup tools show the CNAME and its resolution from outside your network, and the HTTP Headers Checker shows the response and server headers of the subdomain. A community-maintained project on GitHub, "can-i-take-over-xyz", documents which providers are known to allow claims of deleted resource names and how their error pages look.
| Signal | Meaning | Priority |
|---|---|---|
| CNAME target returns NXDOMAIN | Target deleted or never existed | High, verify at the provider |
| Provider error page such as "no such app" | Resource name probably unclaimed | High |
| NS delegation answers REFUSED | Hosted zone likely deleted | Critical |
| Target under an unregistered domain | Anyone can register it | Critical |
| Record points at a working site you do not recognise | Possibly already taken over, or an unknown project | Investigate immediately |
If you find one
Remove the dangling record, or point it at something you control, as the first step. Removing the record ends any takeover immediately once caches expire, whether or not someone has already claimed the resource. Do not try to claim the resource at the provider as a test; fix your own DNS instead.
- Delete or correct the DNS record.
- If the subdomain served someone else's content, record what it served and when, for your incident process.
- Revoke certificates issued for the subdomain if you can identify them, for example through certificate transparency logs.
- Invalidate sessions if cookies were scoped to the parent domain.
- Review allowlists, CSP and OAuth settings that trusted the subdomain.
- Find out how the record was left behind and fix that process.
Tell users if the subdomain was used for phishing or served login pages. A short, factual notice with the dates and what to do, such as resetting passwords entered there, limits the damage more than silence does.
Certificate transparency logs are useful for the investigation: every publicly trusted certificate is logged, so a certificate for your subdomain issued to someone else is visible there. Monitoring CT logs for your domain also gives early warning of takeovers you have not found yet.
Preventing takeovers
Delete DNS first, resources second
When decommissioning, remove the DNS record before deleting the cloud or SaaS resource, and wait for the TTL. Reversing that order creates a window, sometimes permanent, in which the record points at a free name. Put this order into runbooks and infrastructure-as-code pipelines.
Manage DNS as code
When DNS records live in the same repository as the infrastructure they point at, removing a resource and its record happens in one change. Reviews also make it obvious when someone adds a CNAME to an external service, with an owner attached.
Use provider domain verification
Many platforms let you prove ownership of a custom domain with a TXT record before they serve it. Where a provider supports this, a new customer cannot attach your subdomain to their resource without also controlling your DNS. Prefer providers that require it.
Inventory and scan continuously
- Keep an owner and purpose for every externally pointing record.
- Scan all zones on a schedule for the signals in the table above.
- Include expired-domain checks for CNAME, MX and NS targets.
- Watch certificate transparency logs for unexpected certificates on your names.
- Avoid wildcard DNS records that point at shared hosting platforms.
Domain migrations and vendor changes are the moments when dangling records are created most often. The domain migration checklist includes the clean-up step, and the CSP guide explains why wildcard subdomain allowlists deserve a second look.
Automating the scan
A small script run weekly against your zone exports catches most dangling CNAMEs. It resolves each target and flags those that no longer exist. It deliberately makes no requests to claim anything and does not probe other people's systems beyond ordinary DNS lookups.
import dns.resolver
records = [
("docs.example.com", "example-docs.hosting.example.net"),
("status.example.com", "example.status.example.org"),
]
resolver = dns.resolver.Resolver()
resolver.lifetime = 5
for name, target in records:
try:
resolver.resolve(target, "A")
state = "ok"
except dns.resolver.NXDOMAIN:
state = "DANGLING: target does not exist"
except dns.resolver.NoAnswer:
state = "check: target has no A record"
except dns.exception.DNSException as error:
state = f"check: {error.__class__.__name__}"
print(f"{name:<28} -> {target:<40} {state}")A target that resolves is not automatically safe, because many platforms answer for every name under their domain and show an error page for unclaimed ones. Extend the scan with an HTTP request to each subdomain and a list of the error page texts of the providers you use. Treat every hit as a ticket for the record's owner.
Preview environments and wildcards
Modern delivery pipelines create short-lived environments, such as a preview site per pull request at pr-123.preview.example.com. When the pipeline creates DNS records automatically, it must also remove them when the environment is destroyed, including when a job fails half-way. Otherwise records accumulate faster than any manual review can keep up with.
Wildcard records like *.preview.example.com pointing at a shared platform avoid per-environment records but carry their own risk: every name under the wildcard points at the platform, whether or not you created a resource for it. Use wildcards only on platforms that require domain ownership verification for custom hosts, and keep them on a dedicated subdomain rather than your main domain.
Who owns the problem
Takeovers sit between teams: DNS is often run by infrastructure or IT, while the cancelled service belonged to marketing, documentation or a product team. Nobody feels responsible for a record they did not create. Assigning an owner to every external record, and making DNS clean-up part of cancelling any vendor contract, closes that gap.
A lightweight register of external records works well in practice: the record name, the target, the service, the owning team and the contract or ticket that created it. When a contract ends, procurement or the service owner triggers removal of the listed records. The register also answers the first question in any incident, which is who is responsible for the name.
Security teams can help with regular scans and by treating dangling records as vulnerabilities with a severity and a deadline. Bug bounty programs report many takeovers each year, which shows how common the problem is, and how cheap it is to prevent compared with handling a phishing incident on your own domain.
FAQ
Is subdomain takeover a vulnerability in the cloud provider?
Usually it is a configuration issue on the domain owner's side: a DNS record points at a resource they no longer own. Providers can reduce the risk with domain verification, but the reliable fix is removing dangling records.
Can a takeover affect the main domain?
Not the main site directly, but cookies scoped to the parent domain, CSP or CORS rules that trust all subdomains, and user trust in the domain name can all be abused from a subdomain.
Does DNSSEC prevent subdomain takeover?
No. DNSSEC protects the integrity of your records, but the dangling record is a legitimate, correctly signed record pointing at a resource someone else now controls.
How often should I scan for dangling records?
Continuously or at least weekly for organisations with many zones and vendors, and always after decommissioning services or migrating DNS.
Are A records safe from takeover?
Safer, but not safe. An A record pointing at a released cloud IP address sends traffic to whoever is assigned that IP next.
Can a takeover happen on the root domain?
Rarely, because the apex cannot be a CNAME. It can happen with apex records that point at released cloud IP addresses, or when the whole domain's name servers are on a domain that expired.
What should a vendor offboarding checklist include?
Remove DNS records pointing at the vendor, revoke DKIM keys and SPF includes they used, remove their verification TXT records, and check allowlists and OAuth settings that named their hosts.
Should I test by claiming the resource myself?
Removing or correcting your DNS record is the right fix and needs no test claim. Creating resources at providers to prove a takeover is best left to authorised security testing with the provider's rules in mind.
Sources
- OWASP Web Security Testing Guide, WSTG-CONF-10: Test for Subdomain Takeover
- Microsoft Learn: Prevent dangling DNS entries and avoid subdomain takeover
- RFC 6265: HTTP State Management Mechanism (cookie Domain attribute)
- RFC 6962: Certificate Transparency
- can-i-take-over-xyz (community list of provider behaviour)