Subdomain takeover
A dangling DNS record pointing at a de-provisioned third-party resource lets an attacker claim that resource and serve their own content on your trusted subdomain.
A subdomain takeover happens when a DNS record for one of your subdomains points at a third-party service that no longer holds the resource it names. The name still resolves, but nobody owns what it resolves to, so an attacker claims that resource and starts serving their own content on something.yourdomain.com.
How a subdomain goes dangling
The classic cause is an ordering mistake during decommissioning. You stand up a marketing site or app on a cloud host, point a CNAME (or A record) at it, and months later tear the host down, but leave the DNS record behind. The record is now a dangling pointer: it references a resource that is gone but re-claimable by name.
; your DNS zone still says:
promo.example.com. CNAME example-promo.herokuapp.com.
; but the Heroku app example-promo was deleted.
; an attacker simply creates a NEW Heroku app named
; "example-promo" and now controls https://promo.example.comAny service that lets you claim a resource by a name you choose is a candidate. Common ones:
- S3 buckets (
NoSuchBucket) and CloudFront distributions. - Heroku apps.
- GitHub Pages repositories.
- Azure App Service, Traffic Manager, and blob storage.
- Netlify, Vercel, Fastly, and other CNAME-based hosts.
Why it matters
This is not a defaced-page nuisance. Serving attacker content from a subdomain your users already trust unlocks several higher-impact attacks:
- Phishing on a trusted origin. No lookalike typo domain needed, the padlock and the real brand name are genuine.
- Cookie theft. Cookies scoped to the parent domain (
Domain=.example.com) are sent by the browser to *every* subdomain, so each request a victim's browser makes to the attacker's subdomain hands those cookies to the attacker's server, includingHttpOnlysession tokens that page JavaScript can't even read. - Allow-list bypass. A CSP that trusts
*.example.com, an OAuthredirect_uriallow-list, or a CORS policy that trusts your subdomains now trusts the attacker.
How to detect it
Detection is a three-step funnel: enumerate your subdomains, keep the ones whose record points at a third-party service, then check whether that service returns its unclaimed-resource fingerprint.
# 1. resolve and read the CNAME target
dig +short promo.example.com CNAME
# example-promo.herokuapp.com.
# 2. fetch the subdomain and look for the service's "not found" page
curl -s https://promo.example.com | grep -i "No such app"
# Heroku: "No such app"
# S3: "NoSuchBucket"
# GitHub Pages: "There isn't a GitHub Pages site here"A matching fingerprint tells you takeover is possible, not that it happened, some 404 pages are benign and vendor error strings drift over time. You only confirm by actually claiming the resource and serving proof, which is intrusive: do it only on assets you own or are explicitly authorised to test. Register the resource, serve a single harmless marker file, then release it, never leave attacker-controlled content live on someone's domain.
Tools like subzy, nuclei's takeover templates, and dnsReaper automate the fingerprint match across a whole subdomain list. Treat every hit as a candidate to verify by hand, not a confirmed finding, and re-check periodically because fingerprints go stale as vendors change their error pages.
How to prevent it
- Fix the teardown order. Remove the DNS record as part of decommissioning, before or at the same time as deleting the cloud resource, so a dangling pointer never exists.
- Inventory everything. Keep a mapping of every DNS record to a live, owned resource, and reconcile it regularly, orphaned records are the whole bug.
- Monitor continuously. Watch your zone for CNAMEs pointing at third parties and for unclaimed-resource fingerprints, so a newly dangling record is caught in hours, not months.
- Use provider verification. Where a service offers domain-ownership verification (GitHub Pages verified domains, bucket ownership checks), enable it so a name can't be silently re-claimed by someone else.