TL;DR: Subdomain takeover happens when a DNS record points to a cloud service (S3, Heroku, GitHub Pages, Fastly, etc.) that has been deleted or deprovisioned, leaving a "dangling" CNAME that anyone can claim. The fix is to audit your DNS records regularly and remove every CNAME that points to a resource you no longer own. Run a free Kalenfy scan to check your domain for dangling DNS records without touching your DNS panel.
Why subdomain takeover is dangerous
When an attacker claims a dangling resource, they can serve arbitrary content at
your subdomain — careers.yourcompany.com or staging.yourcompany.com
— under your brand and your TLS certificate. This enables:
- Credential phishing — a fake login page at a trusted-looking URL
- Cookie theft — if your cookies use
Domain=.yourcompany.com, they are sent to the attacker's subdomain too - CSP and CORS bypass — if your policy whitelists
*.yourcompany.com - Malware distribution — hosting malicious downloads under your brand
- Email spoofing — sending mail from the compromised subdomain
Bug bounty researchers find and report subdomain takeovers constantly. Real-world examples include takeovers of Microsoft, Uber, and Shopify subdomains — all due to dangling CNAMEs to deprovisioned cloud resources.
How subdomain takeover works
- Your team deploys a staging site on Heroku at
yourapp.herokuapp.comand creates a CNAME:staging.yourcompany.com → yourapp.herokuapp.com - The Heroku app is later deleted but no one removes the DNS record
- An attacker registers a new Heroku app at the same address (
yourapp.herokuapp.com) - Now
staging.yourcompany.comresolves to the attacker's content
Which services are most commonly exploited
| Service | Takeover possible? | Detection signal |
|---|---|---|
| GitHub Pages | Yes | 404 from GitHub with custom domain not configured |
| Heroku | Yes | "No such app" error |
| AWS S3 | Yes (bucket name match) | NoSuchBucket XML response |
| Azure App Service | Yes | "App not found" page |
| Fastly | Yes | Fastly error 500 Unknown domain |
| Shopify | Yes | Shopify "Sorry, this shop is unavailable" |
| Ghost (Ghost.io) | Yes | 404 from Ghost |
| Pantheon | Yes | "404 Site Not Found" from Pantheon |
How to find dangling DNS records
Manual audit
Export your DNS zone file and check every CNAME and A record:
- Export from your DNS provider (usually Settings → Export Zone File)
- For each CNAME, resolve the target:
dig CNAME yoursubdomain.yourcompany.com - Visit the resolved URL directly (without your subdomain). If it returns an error page saying the resource doesn't exist, the record is dangling
- Check the error message — each service has a characteristic "not found" page (see table above)
Automated detection
Tools that scan for dangling CNAMEs automatically:
- can-i-take-over-xyz (GitHub) — community-maintained list of vulnerable services and their fingerprints
- Subjack — Go tool that checks a list of subdomains against known takeover fingerprints
- Nuclei — includes subdomain takeover templates
- Kalenfy scanner — passive check on your primary domain for obvious dangling CNAMEs without requiring a full subdomain enumeration
How to fix a dangling CNAME
The fix is straightforward once you identify the dangling record:
- Log into your DNS provider
- Delete the CNAME record pointing to the deprovisioned service
- If the subdomain is still needed, re-provision the service first, then keep the CNAME — or redirect it to an active URL using a URL redirect record
- Verify the subdomain no longer resolves:
dig yoursubdomain.yourcompany.comshould return NXDOMAIN
If the takeover has already happened: delete the DNS record immediately, then report the incident. Check whether the attacker set cookies under your domain (invalidate all sessions), and review whether the subdomain was in any CORS or CSP allow-lists that need updating.
Prevention: process changes that stop this from happening again
- DNS record lifecycle policy: require a ticket to be filed whenever a cloud resource (Heroku, S3, Azure) is deprovisioned, with a step to remove the matching DNS record
- Regular DNS audit: quarterly review of all CNAME records — check that each target still resolves to something you own
- Least-privilege subdomain use: avoid wildcard DNS
(
*.yourcompany.com) unless strictly necessary — it increases the attack surface because any new service can be created under your domain - Monitoring: set up alerts for new DNS records being created or deleted in your zone
- CAA records: add a CAA record to limit which CAs can issue certificates for your domain — an attacker who claims a subdomain can't get a cert from a CA your CAA record excludes
FAQ
Can DNSSEC prevent subdomain takeover?
No. DNSSEC signs the records that exist in your zone — it doesn't prevent a dangling CNAME from being exploited. The attacker isn't tampering with your DNS; they're claiming the resource your DNS legitimately points to. The only fix is to remove the dangling record.
How quickly can an attacker exploit a dangling CNAME?
Within minutes of discovering it. Bug bounty hunters and malicious actors run automated scanners continuously. A dangling CNAME on a forgotten staging subdomain can be claimed in hours of the resource being deleted.
Does this affect A records too (not just CNAMEs)?
Yes, but less commonly. If an A record points to an Elastic IP or cloud IP that you've released, another customer can be assigned that IP. The risk is lower because cloud providers typically cycle IPs and don't let users choose a specific address — but it's worth auditing A records pointing to cloud ranges (AWS: 3.x.x.x, Azure: 20.x.x.x, GCP: 34.x.x.x) if those IPs are no longer yours.