How to Detect Subdomain Takeover (Before an Attacker Does)
A subdomain takeover is the vulnerability almost every big brand has at some point: a forgotten CNAME points at a deprovisioned SaaS service, an attacker registers that service's free name, and suddenly they're serving content at a real subdomain of the real brand — with a valid HTTPS certificate. This guide shows you how to find these before anyone else does. Start free on EdgeDNS — 200 requests/month, no credit card required.
First: what a subdomain takeover actually is
Before we dive into detection, picture the mechanics clearly. A few years ago, somebody on the marketing team wanted to run a blog. They signed up for a hosted SaaS blog platform (Ghost, Medium, WordPress.com, whatever) and got back an address like `brand-marketing.ghost.io`. To make the blog live at `blog.brand.com`, somebody added a CNAME record in DNS that said: "when anyone asks for `blog.brand.com`, send them to `brand-marketing.ghost.io`." The blog went live, people wrote a few posts, and life moved on.
A year later the blog initiative got deprioritized. Somebody cancelled the Ghost account. Marketing moved on to a different tool. Nobody deleted the CNAME record. The DNS is still answering "go to `brand-marketing.ghost.io`" — but that Ghost account no longer exists. If you visit `blog.brand.com` in a browser, you see Ghost's generic "this blog doesn't exist" page served at your real domain.
An attacker notices. They go to ghost.io and sign up for a new account using the exact name `brand-marketing`. Ghost has no record of the old account; the name is available. They claim it. They put whatever content they want in the new account — a phishing page, malware, spam, stolen-credential harvesting. Now `blog.brand.com` serves their content, under your brand, with a valid HTTPS certificate that the browser happily trusts because the CNAME chain is legitimate as far as the browser is concerned.
That's a subdomain takeover. The pattern is identical across dozens of SaaS services, and the attack requires almost no sophistication. Anybody with a browser, an email address to sign up with, and a domain-monitoring script can find and exploit one. The only thing protecting most brands is luck — until somebody runs a scan.
The attack in one paragraph
A subdomain takeover happens when a subdomain of your brand points (via a dangling CNAME) at a SaaS service that you no longer control. An attacker re-registers the service account under the same name you originally used, and from that moment on the attacker controls content served at your real subdomain. The classic example is `blog.brand.com` pointing at a Heroku app that was deleted years ago — an attacker claims the Heroku name, puts up a phishing page, and the victim sees a legitimate-looking HTTPS site under the real brand.
This attack pattern has produced public findings against Microsoft, Tesla, Uber, Starbucks, and hundreds of smaller brands. Bug-bounty hunters farm it continuously. The fix is always the same: delete the dangling CNAME and audit for others.
Why you should care (even if you think you do not)
Subdomain takeovers are dismissed by people who haven't thought them through. "It's just a blog subdomain — who cares?" is the first reaction, and it misses the three actual risks.
First, cookies scoped to the parent domain are game over. When a browser sees `blog.brand.com`, it happily sends cookies scoped to `.brand.com` along with the request — including session cookies if a user is logged into `app.brand.com`. An attacker controlling the takeover can harvest those sessions and log in as the user elsewhere in your ecosystem. The blog subdomain that seems inconsequential suddenly becomes a session-hijacking vector for your authenticated surface.
Second, the HTTPS is legitimate. The attacker's takeover site serves the same valid SSL certificate your brand would — because the certificate is issued based on DNS control, and DNS still points at the attacker's service. No browser warning. No scary red bar. The victim sees a padlock icon and trusts the page. This is what makes takeovers devastating: they bypass every trust signal a user is trained to look for.
Picture this in real life. A fintech company ran a Heroku-hosted status page at `status.fintech.com` during 2020. In 2022 they migrated to StatusPage.io and deleted the Heroku app. Nobody deleted the CNAME. In 2024 an attacker claimed the Heroku name and served a phishing page at `status.fintech.com` telling users their accounts had been flagged and they needed to log in at a provided link. Users who had saved `status.fintech.com` in bookmarks clicked through. Several credentials were stolen before somebody from support noticed the screenshot in a customer complaint. The takeover had been live for eleven days.
Three questions this guide answers. If any of these have crossed your mind, keep reading:
Do I have any dangling CNAMEs pointing at deprovisioned SaaS accounts I forgot about?
If an attacker registered those service names right now, would they control a subdomain of my brand?
What's the fastest way to audit my entire DNS for takeover risk?
What happens if you skip this entirely. Your brand accumulates takeover-vulnerable subdomains every time a team deprovisions a SaaS account without cleaning up the DNS. Eventually an attacker finds one. The damage depends on what they do with it — phishing is the common outcome, but malware delivery and credential theft both show up in the case studies.
The anatomy of a takeover
Every subdomain takeover follows the same three-part structure. Understanding the structure makes the detection work obvious.
Part 1: the CNAME. Somewhere in your DNS zone, a CNAME record exists that points at a hostname on a SaaS provider. `blog.brand.com → brand-marketing.ghost.io` is the canonical example. The CNAME itself is correct — nothing wrong with it. The problem is the target.
Part 2: the dangling target. The SaaS account that the CNAME points at has been deprovisioned. Visiting `brand-marketing.ghost.io` directly now returns the service's generic "this doesn't exist" page — something like "There isn't a GitHub Pages site here" for GitHub Pages, or "No such app" for Heroku, or an `HTTP 404 NoSuchBucket` for AWS S3. Each service has a distinctive signature in its response when the target is dangling. This is what detection tools match against.
Part 3: the reclaimable name. The SaaS provider doesn't reserve deleted names. If somebody registers a new account using the same name as the deleted one, the service happily gives them ownership. The attacker controls the same hostname the CNAME still points at. They can now serve whatever they want.
The attack is the combination of all three. Any one of them alone is harmless: a CNAME with a live target is fine; a deleted SaaS account that's not referenced by any CNAME is fine; a reclaimable name that nobody's CNAME points at is fine. The vulnerability is the alignment of all three.
The 15+ services where this keeps happening
The canonical running list of takeover-vulnerable services is the can-i-take-over-xyz project on GitHub. The current list has dozens of services across several categories:
Static hosting: GitHub Pages, GitLab Pages, Bitbucket Cloud, Netlify, Vercel.
Platform-as-a-service: Heroku, Render, Fly.io, Railway.
Cloud object storage: AWS S3, Azure Blob Storage, Google Cloud Storage.
CDNs and edge: Fastly, CloudFront, Azure Front Door, Cloudflare Workers.
Content platforms: Ghost, WordPress.com, Tumblr, Cargo Collective, Readme.io.
E-commerce: Shopify (older, partially-fixed pattern), Squarespace.
Support / marketing tooling: UserVoice, Help Scout, HubSpot (specific configurations), Unbounce, Strikingly.
Each service has its own signature — a specific response body, HTTP status code, or header that indicates the target has been deprovisioned. Automated detection tools maintain a database of these signatures and match them against live HTTP responses. Projects like subjack, Subzy, and commercial tools like Detectify and EdgeDNS all use roughly the same approach.
A warning: the list evolves. Services add protection (Shopify now rejects takeover attempts on most subdomains, for example). New services appear and briefly become vulnerable before patching. Rely on a tool that updates its signature list continuously, not on a list you check once a year.
How to audit your own domain
There are three progressively more thorough ways to check, depending on how much time you have.
Fastest (recommended): run the EdgeDNS subdomain-takeover check against your domain. It enumerates common subdomain names, looks for CNAMEs pointing at known-vulnerable services, and confirms each finding by matching the HTTPS response body against the service's takeover signature. Free on every plan.
Easier still (if you're using AI): if you've connected the EdgeDNS MCP server to Claude, ChatGPT, or Gemini, ask: "Check example.com for any dangling CNAMEs vulnerable to subdomain takeover, and tell me which services are involved." The AI runs the check, reads the output, and explains any findings conversationally.
Nerdy way (command line): for each subdomain you care about, look up its CNAME target, and if the target matches a known SaaS pattern, fetch it and look for the takeover signature.
# List CNAMEs for a subdomain and its target
dig CNAME blog.example.com +short
# Check the target directly — if you see a "no such site" response
# from a known SaaS, the subdomain is takeover-vulnerable
curl -sI https://blog.example.com | head -5
# Or use the EdgeDNS API (returns structured findings)
curl -s "https://api.edgedns.dev/v1/domain/subdomain-takeover?domain=example.com" \
-H "Authorization: Bearer YOUR_API_KEY" | jq '.data.findings'Auditing for takeovers from Python
If you're scripting a recurring zone audit, here's a minimal Python example. It returns the structured findings list and exits non-zero if any high-risk takeovers are detected — suitable for a cron-driven monitoring job or a CI gate on a domain-management repo.
import os
import sys
import requests
API_KEY = os.environ['EDGEDNS_API_KEY']
def audit_takeovers(domain: str) -> list[dict]:
r = requests.get(
'https://api.edgedns.dev/v1/domain/subdomain-takeover',
params={'domain': domain},
headers={'Authorization': f'Bearer {API_KEY}'},
timeout=30,
)
r.raise_for_status()
return r.json()['data'].get('findings', [])
def main(domain: str) -> int:
findings = audit_takeovers(domain)
high_risk = [f for f in findings if f.get('severity') == 'high']
print(f"Total findings: {len(findings)}")
print(f"High-risk: {len(high_risk)}")
for f in high_risk:
print(f" ! {f['subdomain']} -> {f.get('target')} ({f.get('service')})")
return 1 if high_risk else 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1] if len(sys.argv) > 1 else 'example.com'))Confirming a finding before you report it
Detection tools sometimes produce false positives — a CNAME might point at a SaaS hostname that's merely returning an error for unrelated reasons. Before filing a bug, opening a ticket, or handing the finding to a security team, confirm the takeover is actually exploitable.
Step 1: verify the CNAME still points at the target. Run the DNS lookup fresh. DNS can be cached; the target might have been updated since the initial scan.
Step 2: check the HTTPS response body. The target should return the SaaS provider's characteristic "this doesn't exist" page. A generic HTTP 404 from an origin server is not the same signal — that usually means the content simply hasn't been published yet, not that the account has been deleted.
Step 3: try to claim the SaaS account yourself. Go to the provider (Ghost, Heroku, GitHub Pages, whatever) and attempt to sign up for an account using the exact name that the CNAME points at. If the provider lets you claim it — that's your proof. Most ethical disclosure processes expect you to claim and hold the account temporarily while the vulnerability is being fixed, then transfer or release it.
Step 4: do not put real attack content on the claimed account. Serve a single HTML page with the message "Proof of concept — do not exploit. Contact: [your email]." Take a screenshot. That's your evidence.
Ethical researchers use this playbook routinely. The HackerOne Hacktivity stream has hundreds of disclosed subdomain takeovers that follow this exact pattern, complete with the PoC screenshots.
How to fix a takeover-vulnerable subdomain
Once you've confirmed a finding, the fix is usually trivial — but there's a right order.
Step 1: reclaim the SaaS account. If an attacker hasn't already registered the name, go claim it yourself before anyone else does. Hold the account while you fix the DNS.
Step 2: delete the dangling CNAME. Log into your DNS provider's control panel, find the CNAME record for the vulnerable subdomain, and delete it. DNS propagation means the CNAME will stop resolving within minutes to hours depending on the TTL.
Step 3: release the SaaS account. Once the CNAME is gone and you've confirmed the subdomain no longer resolves to the SaaS host, you can release the SaaS account back to the provider (or just keep it indefinitely — it's free for most services).
Step 4: scan for siblings. If one dangling CNAME existed, others probably exist. Run a full scan of your DNS zone to catch the rest. Teams that have deprovisioned one SaaS account in the last five years have usually deprovisioned several, and the cleanup is almost never thorough.
Step 5: add the scan to your recurring monitoring. Takeover risk accumulates every time a team cancels a SaaS account. Monthly or continuous scanning catches new findings before attackers do.
Preventing new takeovers from appearing
Long-term, the question isn't how do I fix today's findings — it's how do I stop creating new ones. The answer is organizational, not technical.
Couple SaaS offboarding with DNS cleanup. When anybody cancels a SaaS account, the same ticket should require deleting the CNAME that pointed at it. Put the rule in your offboarding checklist. Most takeover findings are the result of a cancelled account and an unrelated CNAME that nobody connected to it.
Inventory third-party CNAMEs quarterly. Keep a list of every CNAME in your zone that points at a SaaS provider. Cross-reference it against your active vendor list. Anything on the first list that's not on the second list is a candidate takeover — investigate before it becomes an incident.
Automate the scan. Continuous detection is cheap — much cheaper than responding to a post-takeover incident. Schedule a takeover check to run weekly against your production domain and alert on any finding. The EdgeDNS subdomain-takeover endpoint is designed for exactly this — run it in a cron job or CI pipeline.
Read the current research. The attack patterns evolve. Detectify Labs and the HackerOne Hacktivity stream publish the disclosures that shape what signatures detection tools look for. Reading one disclosure a month keeps you aware of new patterns before they hit your own infrastructure.
Or — if you've connected the EdgeDNS MCP server to your AI assistant — ask it once a month: "Check acme.com for any subdomain takeover vulnerabilities, and tell me if anything has changed since last month." The AI will run the check, read the output, and give you a plain-language summary.
Words you might be wondering about
Subdomain takeover — the attack this guide is about: an attacker claims a SaaS account that a dangling CNAME still points at, giving them control of a real subdomain of your brand.
Dangling CNAME — a DNS CNAME record whose target (another hostname) no longer exists or no longer responds. The name "dangling" comes from the sense of pointing at nothing solid.
CNAME record — a DNS record type that maps one hostname to another, rather than to an IP address directly.
DNS (Domain Name System) — the internet's address book, where CNAMEs and every other record type live.
MCP (Model Context Protocol) — the open standard that lets AI assistants like Claude and ChatGPT call EdgeDNS tools directly.
SaaS (Software as a Service) — hosted software you sign up for, typically giving you a hostname under the provider's domain. Heroku apps get a `.herokuapp.com` hostname; GitHub Pages sites get a `.github.io` hostname; and so on.
Bug bounty — a program run by a company to pay independent security researchers who find and responsibly disclose vulnerabilities. Subdomain takeovers are a staple category in bug bounty programs.
Related Guides
MCP for DNS: How to Talk to Your Domains
Imagine asking Claude, "hey, is my email setup working correctly?" — and getting a real, accurate answer back, instantly. That's what the EdgeDNS MCP server does. This guide explains what MCP is, why it's a big deal, and how to connect it in about a minute.
DNS Propagation Explained: Why Changes Aren't Instant
Ever changed a DNS record and then refreshed your browser, hoping to see the change instantly — but it took hours? That's DNS propagation. This guide explains why it happens, how to check on it, and how to make it as fast as possible next time.
Need Programmatic Access?
Automate domain intelligence with 100+ API endpoints and a free MCP server for AI integration.