Subdomain takeover: a 5-minute guide to the modern threat
A marketing intern set up landing-summer-promo.example.com as a CNAME to a Heroku
app three years ago. The campaign ended. Someone deleted the Heroku app. Nobody touched the DNS.
Today, landing-summer-promo.example.com still resolves to summer-promo.herokuapp.com,
which now returns a 404. Anyone, including an attacker, can register a fresh Heroku app called
summer-promo and serve whatever they want — phishing landing pages, malware downloads,
coupon scams — from your branded subdomain. Browsers will even render it over your wildcard cert.
That's a subdomain takeover. It's been around since 2014, it still happens every week, and detection takes one DNS query.
The pattern
Three ingredients are always present:
- A subdomain whose DNS record (CNAME, NS, MX, sometimes A) points to an external SaaS.
- The resource at that SaaS no longer exists.
- The SaaS allows anyone to claim the freed name.
SaaS providers that fit (3) are the dangerous ones. Heroku, GitHub Pages, Shopify, Fastly, Tumblr, Netlify, Surge.sh, Webflow, Helpscout, AWS Elastic Beanstalk, Azure CloudApp, S3 buckets with the bucket name as part of the URL — these are the classic vectors. The attacker's "claim" is just a free signup with the right slug.
Detection in 30 seconds
Pick a CNAME under your domain, follow it, look at the response. Vulnerable patterns produce very specific signatures:
$ dig +short landing-summer-promo.example.com
summer-promo.herokuapp.com.
$ curl -sI https://summer-promo.herokuapp.com
HTTP/2 404
server: Cowboy
...
<h1>No such app</h1>
"No such app" on Heroku is the canary. Once you see that body served from a CNAME you control, you have a takeover-vulnerable subdomain. Same pattern with different bodies on every other host:
| Provider | Body / signature |
|---|---|
| GitHub Pages | There isn't a GitHub Pages site here. |
| Heroku | No such app + Cowboy server |
| Shopify | Sorry, this shop is currently unavailable. |
| Fastly | Fastly error: unknown domain |
| Netlify | Not found - Request ID: ... 404 page |
| S3 (vanity URL) | NoSuchBucket XML response |
| Tumblr | Whatever you were looking for doesn't currently exist |
| Webflow | The page you are looking for doesn't exist or has been moved |
| Helpscout | No settings were found for this company |
UnveilScan's subdomain_takeover checker matches this table against every CNAME we
discover via crt.sh certificate transparency logs. The Extended profile runs it automatically.
Why CT logs make this a continuous threat
Every TLS certificate ever issued for a subdomain is logged publicly to Certificate
Transparency. crt.sh indexes them and lets anyone enumerate every subdomain that
ever existed for a given apex. Attackers run the same enumeration. They find your
landing-summer-promo.example.com from the dead 2023 wildcard cert, check whether
the underlying SaaS slot is claimable, and if yes, claim it.
"It's just a forgotten subdomain" is no longer hidden by obscurity. The attacker tooling is better than yours; assume every subdomain you've ever certified is a target.
Real impact
A successfully taken-over subdomain delivers, depending on the attacker's goals:
- Phishing pages served from a domain users trust. Browsers show the green padlock; the wildcard cert covers it. Conversion rates beat any look-alike domain.
- Cookie theft via
document.cookieif your app sets cookies on.example.com(without__Host-prefix). Subdomain takeover bypasses Same-Origin Policy because it IS your origin. - OAuth / SSO redirect attacks if your IdP allowlist contains
*.example.com. - SEO poisoning — attacker-served content gets indexed under your reputable domain.
- Brand damage when security researchers tweet about your dangling subdomain.
Prevention checklist
- Deprovision in the right order. Always remove the DNS record before deleting the SaaS resource. Most takeovers happen because somebody did the SaaS cleanup first.
- Use a CNAME-to-apex pattern only when necessary. An A/AAAA record to your own infrastructure can't be hijacked — only the record-pointing-to-external-SaaS pattern is vulnerable.
- Inventory continuously. Schedule a weekly subdomain enumeration via CT logs (UnveilScan does this on Extended). When a "ghost" subdomain shows up — owner unknown, app unreachable — burn it down.
- Pre-claim risky names. Some teams pre-register their company slug on the major vulnerable platforms (Heroku, Shopify, etc.) so attackers can't claim them later.
- Lock CAA records. A CAA record limits which CAs can issue certs for your domain. Won't stop the takeover but slows down attackers trying to mint a new cert.
What UnveilScan does about it
Our Extended profile runs the subdomain_takeover checker on every CNAME found in CT
logs for your apex. We test against 15 SaaS signatures including all the providers in the table
above, plus Atlassian, Bitbucket, ReadMe, and a few less-common offenders. Findings are
HIGH by default — they're directly exploitable, not theoretical.
On a Pro plan with scheduled scans, this runs daily. New takeover-vulnerable subdomain → alert email/webhook within 24 hours. That's the gap between "intern set this up three years ago and it's now serving phishing" and "we caught it tonight, fixed by morning".
Audit your subdomains for takeover vectors
Extended scan covers all CT-discovered subdomains, 15 SaaS signatures, plus 86 other passive checkers.
See pricing