Subdomain Takeover: How Dangling DNS Records Get Hijacked
A subdomain you forgot about can become an attacker's home base on your own domain. It usually starts with a DNS record that outlived the service it pointed to. This guide walks through how that happens, why a hijacked subdomain is more dangerous than it looks, and the steps that close the gap for good.
What a subdomain takeover is#
A subdomain takeover is what happens when a DNS record for one of your subdomains points to a third party service that no longer claims that hostname. The record still resolves and still sends visitors to the provider, but the provider has nothing serving there anymore. An attacker who registers the same hostname on that provider then controls whatever loads at your subdomain. The DNS record never changed hands. Only the thing sitting behind it did.
The usual culprit is a CNAME record. A CNAME (canonical name) is a DNS entry that aliases one hostname to another, so blog.example.com might be a CNAME to your-app.herokuapp.com. Visitors who type the friendly name get quietly routed to the platform hosting the real content. That indirection is convenient, and it is also exactly where the danger lives. When the Heroku app is deleted but the CNAME is not, the alias keeps pointing at a name that anyone can now grab.
A record in this state is called a dangling DNS record. It is dangling because it points to a backend resource that no longer exists. The hostname resolves fine from the outside, so monitoring that only checks whether DNS answers will report everything as healthy. The problem only becomes visible when you ask what is actually answering on the other end.
How a dangling CNAME becomes a takeover
How dangling records appear#
Almost every dangling record is created by ordinary teardown work done in the wrong order. Someone spins up a resource on a hosted platform, points a subdomain at it, and ships. Months or years later the resource is no longer needed, so it gets deleted. The DNS record, which lives in a completely separate system and is often managed by a different team, gets forgotten. The service is gone but the signpost to it remains.
The platforms that show up most often in real takeovers share one trait. They let you claim a hostname simply by creating a resource with the right name, with no proof that you own the domain pointing at it. A few common examples:
- Cloud storage buckets such as Amazon S3, where a deleted bucket frees the name and a CNAME to it returns a NoSuchBucket error until someone creates a bucket of the same name.
- Static hosting like GitHub Pages, where an unclaimed custom domain shows the "There isn't a GitHub Pages site here" page and can be claimed by adding that domain to another repository.
- App platforms such as Heroku, where a removed app returns "No such app" and the app name becomes available for anyone to register.
- Azure resources like App Service, Traffic Manager, and CDN endpoints, where deleting the resource releases the *.azurewebsites.net or similar name back into a shared pool.
- SaaS and marketing tools that host content on a vendor hostname, where an expired or cancelled account leaves the vendor with no record for your custom domain.
Not every provider is exploitable. Many now require domain verification, so a dangling CNAME to them is dead rather than dangerous. The risk depends entirely on whether the specific provider lets an unrelated account claim the released hostname. That distinction is why generic DNS hygiene matters more than memorizing a list. A provider that is safe today may change its verification model tomorrow, and a record you stopped thinking about years ago is the one that surprises you.
The record outlives the resource by design
DNS and the hosting platform are separate systems with separate owners. Deleting an app or a bucket does nothing to the CNAME that points at it. Unless removing the DNS record is written into your decommission checklist, the default outcome is a dangling entry that nobody is watching.
How attackers fingerprint targets#
Finding a vulnerable subdomain is largely automated. An attacker starts by enumerating subdomains, pulling candidate names from certificate transparency logs, passive DNS datasets, and brute force wordlists. Certificate transparency is especially useful to them because every TLS certificate ever issued for your domain is published to public logs, which quietly advertises hostnames you may have long forgotten.
With a list of subdomains in hand, the attacker resolves each one and sends an HTTP request. The key move is fingerprinting, which means matching the response against a database of known signatures. When a provider has no resource for a hostname, it returns a recognizable error. Amazon S3 answers a direct request with NoSuchBucket. GitHub Pages serves a page reading "There isn't a GitHub Pages site here". Heroku returns a 404 with "No such app". Each of those strings is a tell that the hostname is unclaimed and the subdomain in front of it is up for grabs.
The community keeps these signatures in a public catalog known as can-i-take-over-xyz, which records, per provider, whether a takeover is possible and what the unclaimed response looks like. Scanners read from it to flag candidates automatically, which is why the gap between a record going dangling and someone noticing can be very short. The same catalog is just as useful to defenders, because it tells you precisely which of your providers are exploitable and which only leave dead records behind.
Why it is dangerous#
A hijacked subdomain is far worse than a defaced parking page, because the attacker is now serving content from a hostname your users and your own systems already trust. The browser shows your domain in the address bar with no warning, and the attacker can usually obtain a valid TLS certificate for the hostname in minutes, so even the padlock looks right.
Phishing is the most direct abuse. A login page hosted on accounts.example.com is dramatically more convincing than the same page on a lookalike domain, because it genuinely is your domain. Anyone who checks the address bar before entering a password is reassured by exactly the wrong thing.
The damage often reaches the parent domain too. Cookies set with a leading dot, such as a session cookie scoped to .example.com, are sent to every subdomain, so attacker code on a hijacked subdomain can read any of those that are not flagged HttpOnly. That can hand over an authenticated session for the main application. The takeover can also defeat your own allowlists. A Content Security Policy or CORS configuration that trusts *.example.com will happily load scripts from the attacker's subdomain, since as far as the policy is concerned the content really did come from your domain.
What an attacker can do once they hold a subdomain
- Host phishing pages on a trusted hostname that carries your brand and a valid certificate.
- Read parent-domain cookies that lack HttpOnly, including session tokens scoped to .example.com.
- Pass Content Security Policy and CORS checks that allowlist a wildcard of your own domain.
- Damage reputation and deliverability, since email and links from your domain may end up flagged or blocklisted.
How to find dangling records#
Auditing your own domain uses the same two steps an attacker would. First enumerate every subdomain you have, pulling from your DNS provider's zone export, certificate transparency logs, and any internal inventory. Then resolve each one and look at what actually answers. A subdomain whose CNAME points at a provider but returns that provider's unclaimed signature is a record you need to fix today.
For a quick manual check on a single hostname, dig shows you where a name points and curl shows you what is answering there.
# Resolve a subdomain and see exactly where it points dig +short blog.example.com CNAME # your-old-app.herokuapp.com. # Then request the target directly and read the body curl -sI https://blog.example.com # Look for provider error pages like: # 404 "No such app" (Heroku) # "There isn't a GitHub Pages site here" (GitHub Pages) # NoSuchBucket (Amazon S3)
For a whole zone, loop over your subdomain list and flag any that resolve to a provider while returning a known unclaimed signature. The script below is a starting point you can extend with more provider signatures.
# Pull every record from a zone, then check each CNAME target.
# This loop flags subdomains whose CNAME resolves but returns
# a known "unclaimed" signature from the provider.
for sub in $(cat subdomains.txt); do
target=$(dig +short "$sub" CNAME)
[ -z "$target" ] && continue
body=$(curl -s --max-time 10 "https://$sub")
echo "$body" | grep -qiE "no such app|there isn't a github pages|nosuchbucket" \
&& echo "DANGLING: $sub -> $target"
doneManual checks are fine for a one time sweep, but subdomains come and go constantly, so a record can go dangling the week after you finish auditing. The durable answer is continuous monitoring that re-resolves your hostnames on a schedule and alerts when one starts returning a takeover signature. SiteSecurityScore looks at your DNS and the responses behind it as part of a scan, so dangling records surface as findings rather than waiting for a researcher or an attacker to spot them first.
Prevention and remediation#
Preventing takeovers comes down to controlling the order in which you create and destroy things, and never losing track of which DNS record belongs to which resource. None of it is exotic. It is mostly about making DNS a first class part of your provisioning and teardown rather than an afterthought handled by a different team.
The practices that close the gap
- Remove the DNS record as part of decommissioning a service, in the same change that deletes the resource, so a dangling entry is never created in the first place.
- Claim the hostname on the provider before you point DNS at it, so the order of operations never leaves a window where the name is unclaimed but already referenced.
- Keep a living inventory that maps every DNS record to a resource, an owner, and an expected lifecycle, and reconcile it on a regular cadence.
- Avoid wildcard CNAMEs aimed at third party platforms, because a single *.example.com alias to a provider can expose every name under it at once.
- Gate DNS changes through review or a CI check, so adding or removing a record is a deliberate, auditable step rather than a quiet edit in a console.
If you discover a record that is already dangling, the fix is immediate and usually simple. Delete the DNS record if the subdomain is no longer needed. If it is still needed, recreate the backing resource on the provider and reclaim the hostname yourself before anyone else does, then decide whether the subdomain should keep pointing there at all. The OWASP Subdomain Takeover Prevention Cheat Sheet is a good reference for the full lifecycle and for provider specific notes.
Wildcard records widen the blast radius
A wildcard CNAME such as *.example.com pointed at a third party platform means every conceivable subdomain resolves to that provider. If the provider lets an account claim arbitrary hostnames, an attacker can take over names you never even created. Prefer explicit records for the subdomains you actually use.
FAQ#
What is a subdomain takeover?
A subdomain takeover happens when a DNS record for one of your subdomains, usually a CNAME, points to a third party service that no longer claims that hostname. The service released the name when the underlying resource was deleted, but the DNS record was left behind. An attacker who registers the same hostname on that service then controls whatever loads at your subdomain, even though the DNS record still belongs to you.
What is a dangling DNS record?
A dangling DNS record is an entry that points to a backend resource that no longer exists. The classic case is a CNAME aimed at an S3 bucket, a GitHub Pages site, a Heroku app, or an Azure endpoint that has since been deleted. The DNS still resolves and sends visitors to the provider, but the provider has no resource for that hostname, which leaves the name open for anyone to claim.
Why is a subdomain takeover dangerous if it is just a subdomain?
The subdomain still carries your domain name, so visitors and browsers treat it as yours. An attacker can host a convincing phishing login on it, read cookies that were scoped to the parent domain with a leading dot, and slip past Content Security Policy or CORS rules that allowlist your own wildcard domain. A valid TLS certificate is usually trivial to obtain for the hostname, so there is no browser warning to tip anyone off.
How do attackers find vulnerable subdomains?
They enumerate subdomains through certificate transparency logs, brute force wordlists, and passive DNS data, then resolve each one and inspect the response. Many providers return a recognizable error when a hostname is unclaimed, such as NoSuchBucket from S3 or the There isn't a GitHub Pages site here page. Tooling fingerprints these responses against a public database of known signatures to flag which subdomains can be claimed.
How do I prevent subdomain takeover?
Remove the DNS record at the same time you decommission the service it points to, and treat that as part of the teardown rather than an afterthought. Claim the hostname on the provider before you create the DNS record, so the order of operations never leaves a window open. Keep a living inventory that maps every DNS record to a resource and an owner, scan it on a schedule for dangling entries, and avoid wildcard CNAMEs that point at third party platforms.
References
Related articles
Find Dangling Records Before Attackers Do
Run a free scan to surface dangling DNS records and risky configurations across your domain, then turn on monitoring so a record that goes stale next month gets flagged the day it happens.