Subdomain takeover: detect and fix
Among everything a passive scan reports, this is one of the few findings that is almost always exploitable rather than theoretical — and one of the cheapest to fix, once you know which ones are real.
How it happens
Nobody creates a takeover on purpose. It is the residue of a normal decommissioning that stopped one step short.
A team points a subdomain at a third-party service with a CNAME: a documentation tool, a status page, a landing-page builder, a CDN. Months later the subscription is cancelled or the resource deleted. The DNS record stays, because deleting DNS is a different system, owned by a different team, and nothing forces the two actions to happen together.
docs.example.com. CNAME example-docs.someprovider.net.
the provider account is gone
the name is free to claim againWhoever registers that name at the provider now serves whatever they want from docs.example.com. Not a look-alike domain. Yours.
The asymmetry is what makes it attractive: claiming an unused slot on a SaaS platform costs nothing and takes a minute, while the name it grants carries a reputation built over years.
Finding your dangling records
You need two things: the full list of your subdomains, and the resolution status of each CNAME.
Enumeration comes first, and it is entirely passive: Certificate Transparency logs, passive DNS, search indexes. The records at risk are precisely those nobody remembers, so working from your own documentation is the one method guaranteed to miss them.
Then resolve each candidate:
> dig +short CNAME docs.example.com > example-docs.someprovider.net. > > dig +short example-docs.someprovider.net > (empty — the target does not resolve)
A CNAME whose target no longer resolves is your first-priority candidate. But an empty answer is a signal, not a verdict.
The other shape, which is easier to miss Plenty of takeoverable records resolve perfectly well. The provider still answers, on shared infrastructure, and returns an error page saying the resource is unclaimed. DNS looks healthy; the vulnerability is in the HTTP response.
That is why detection reads the response body, not just the resolution. Each provider has its own signature: "There isn't a GitHub Pages site here", "NoSuchBucket", "no such app" on Heroku, "Do you want to register" on some page builders.
Confirming without crying wolf
This is where most takeover reports go wrong, and it matters because a false positive costs you an afternoon and some credibility.
A dangling CNAME is not automatically claimable. Several providers added protections precisely because this class of bug embarrassed them:
- GitHub Pages requires domain verification before a custom domain can be attached to a new organisation.
- Some platforms retain a claimed hostname for a grace period after cancellation.
- Others bind the hostname to the account that first verified it, permanently.
So the honest sequence is: the record dangles, the provider returns an unclaimed-resource signature, and that provider still allows a new account to attach that hostname. Only all three together make it exploitable.
Do not test by claiming a resource on a domain you do not control, and do not host proof-of-concept content on a live subdomain of a third party. Read the provider documentation on custom domains instead: it tells you whether verification is required, which answers the question without touching anything.
Practical note: a record you cannot exploit today may become exploitable when the provider changes its policy. A dangling CNAME should be deleted whether or not it is currently claimable, because the fix costs one DNS change and the risk is not static.
What it actually gets an attacker
Phishing is the obvious use, and it is the least interesting one.
Because the hostname is genuinely yours, three technical consequences follow that people rarely anticipate.
Cookies A cookie set with Domain=.example.com is sent to every subdomain, including the one now under someone else's control. If your session cookie is scoped to the parent domain rather than to a specific host, a takeover reads it. This alone turns a forgotten status page into a session hijack.
Allowlists that trust your own wildcard Configurations across your stack quietly trust anything under your domain:
- CORS policies allowing *.example.com
- Content Security Policy directives listing *.example.com as a script source
- OAuth redirect_uri allowlists accepting any subdomain
Each of those turns a takeover into something sharper than phishing: script execution trusted by your own CSP, or an authorisation code delivered to an attacker-controlled endpoint that your identity provider considers legitimate.
Certificates and reputation The new occupant can obtain a valid TLS certificate for the hostname, because they demonstrably control it. Padlock, correct domain, no warning. And whatever they host is attributed to you, including by blocklists.
Fixing it
The fix is short, which is the good news.
- Delete the DNS record if the service is genuinely retired. This is the right answer in the large majority of cases.
- Or reclaim the resource at the provider if the subdomain is still needed, then re-point it deliberately.
Do it in that order and do it now: the window matters more than the paperwork. A dangling record is exploitable by whoever finds it first, and the enumeration that finds it is available to everyone.
Then check what the name could have reached. If the subdomain was live for a while under someone else's control, treat it as a possible session and credential exposure rather than a defacement: review cookie scoping, and rotate anything that a page on that hostname could have collected.
Making it not come back
Every organisation fixes its dangling records once. The ones that stay fixed changed a process, not a record.
- Put DNS in the decommissioning checklist. Retiring a service and retiring its DNS record must be one task with one owner, not two tasks in two systems.
- Manage DNS as code, reviewed like code. A CNAME pointing at a provider nobody recognises gets caught in review, which is the cheapest possible moment.
- Scope cookies to the host that needs them, not to the parent domain. This does not prevent takeover; it removes its worst consequence.
- Prefer explicit subdomains over wildcards in CORS, CSP and OAuth allowlists, so one lost name does not inherit trust meant for the whole estate.
- Re-enumerate on a schedule. The list changes every time a project ships.
Frequently asked questions
How do I know if a subdomain is vulnerable to takeover?
Three conditions must hold together. The subdomain has a CNAME pointing at a third-party resource, that resource no longer exists — either the target does not resolve, or the provider returns an unclaimed-resource page — and that provider still allows a new account to attach the hostname. A dangling CNAME alone is not enough, because several providers now require domain verification.
Is a dangling CNAME always dangerous?
Not always immediately exploitable, but always worth deleting. Some providers require domain verification or hold a hostname after cancellation, which blocks the takeover today. Provider policies change, and yours will not be re-reviewed when they do. The fix is a single DNS change, so the cost of removing a record you no longer need is far below the cost of tracking whether it is still safe.
What is the real impact beyond phishing?
Because the hostname is genuinely yours, it inherits trust. Cookies scoped to the parent domain are sent to it, which can mean session hijacking. Allowlists that trust a wildcard on your domain — CORS, Content Security Policy, OAuth redirect URIs — accept it, which can mean script execution your own CSP endorses or authorisation codes delivered to an attacker. The occupant can also obtain a valid TLS certificate, so nothing looks wrong to a visitor.
How do I stop it happening again?
Make DNS removal part of decommissioning, so retiring a service and retiring its record are one task with one owner. Manage DNS as reviewed code, so an unrecognised CNAME is caught at review. Scope cookies to the host rather than the parent domain, and prefer explicit subdomains over wildcards in CORS, CSP and OAuth allowlists — that way a lost name does not inherit trust meant for everything.
See where your own domain stands
A free, fully passive scan. Public data only, no intrusion, no account required.
Scan my domain