Domain-security radar

The subdomain you forgot, that someone else can claim

Point a subdomain at a cloud resource — an S3 bucket, a GitHub Pages site, a Heroku app — then delete the resource but leave the DNS record behind, and you’ve created a dangling pointer to nothing. Anyone can re-register that exact resource and instantly serve their own content on your subdomain: phishing pages with your name on them, cookie theft, OAuth abuse. We find candidates in public Certificate Transparency logs, then check each one ourselves — DNS lookups plus one identified, read-only request, or two if the host answers HTTPS with an empty body and we retry over HTTP. Confirming a delegation adds DNS only; counting the address lookup each request makes, that is up to 12 name resolutions per candidate, and a DNS server may see more than one query for each. In 2025 researchers re-registered ~150 abandoned S3 buckets that once belonged to governments and Fortune 500s.

What the radar has done so far

2,203,984
Subdomains checked
11,875
Delegated to a third-party service
85
Takeover-able (dangling, unclaimed)

A subdomain is counted takeover-able only when its CNAME delegates to a known service AND that service returns its “unclaimed” fingerprint (e.g. S3’s NoSuchBucket) — the same high-precision signal subjack and nuclei use. Confirmed cases are rare and serious; most delegations are live and claimed.

Why this matters

A taken-over subdomain isn’t “just a subdomain” — it inherits your domain’s trust:

  • • Phishing that looks 100% legitimate — the page really is on your domain, so links, filters, and users all trust it.
  • • Cookie & session theft — cookies scoped to *.yourdomain.com can be read from the hijacked subdomain.
  • • OAuth / SSO bypass & brand damage — redirect-URI allow-lists and email/SPF trust can be abused from a subdomain you no longer control.

The fix is free: delete the dangling DNS record, or re-claim the resource you still need.

By service

  • GitHub Pages61 takeover-able of 1,630 delegated
  • Fastly22 takeover-able of 308 delegated
  • Heroku2 takeover-able of 1,149 delegated
  • Shopify0 takeover-able of 7,943 delegated
  • Webflow0 takeover-able of 389 delegated
  • Smugmug0 takeover-able of 109 delegated
  • Pantheon0 takeover-able of 98 delegated
  • Big Cartel0 takeover-able of 86 delegated
  • Strikingly0 takeover-able of 46 delegated
  • Help Scout0 takeover-able of 33 delegated
  • Tumblr0 takeover-able of 31 delegated
  • Ghost0 takeover-able of 12 delegated
  • Hatena0 takeover-able of 12 delegated
  • Read the Docs0 takeover-able of 11 delegated
  • Wordpress0 takeover-able of 9 delegated

Are you exposed?

Check whether any of your subdomains point at a resource you no longer control — a free external scan of your internet-facing surface, no signup.

Check your exposure →

How it works

How do you detect a takeover without claiming anything?

We resolve the subdomain’s CNAME; if it delegates to a known service, we make one read-only GET (HTTPS, then HTTP if that returned nothing) and look for that service’s “unclaimed” response (e.g. “There isn’t a GitHub Pages site here”, “No such app”, “NoSuchBucket”). We never register or claim the dangling resource — that would be the attack.

Why is the takeover count usually low?

Because we hold it to a high bar — both the CNAME delegation and the unclaimed fingerprint must match. Most subdomains delegate to live, claimed resources. A confirmed takeover is rare, which is exactly why it’s worth surfacing.

Why don't you list the affected subdomains?

Publishing them would be a ready-made shopping list for attackers. We keep host names private for responsible disclosure to the owners and publish only aggregate counts. Use the scanner above to check your own subdomains.

Aggregates only. Detect-only: up to 12 name resolutions and one or two identified GETs per candidate, and no other request; we never claim the resource; host names withheld; affected owners notified via responsible disclosure — see our full Responsible Disclosure & Data Handling policy.Last check completed Mon, 02 Nov 2026 01:18:39 GMT.

Frequently asked questions

What is a subdomain takeover?

When a subdomain's DNS record (usually a CNAME) still points at a cloud resource that has been deleted — an S3 bucket, GitHub Pages site, Heroku or Azure app — an attacker can re-create that resource and serve their own content from your subdomain.

Why is a dangling DNS record dangerous?

The attacker controls a real subdomain on your domain, which enables convincing phishing, cookie and session theft, OAuth-redirect abuse, and bypass of domain-based trust. It is hard for users to spot because the subdomain genuinely belongs to you.

How does EchelonGraph detect subdomain takeovers?

It resolves subdomains and flags CNAMEs pointing at unclaimed or deprovisioned third-party targets, then makes one read-only GET to the host root — two if the first returns nothing over HTTPS and we retry over HTTP. Confirming a wildcard delegation or a GitHub Pages claim adds DNS only; counting the address lookup each GET makes, that is up to 12 name resolutions per candidate, including up to three of a probe label of our own, and a DNS server may see more than one query for each. Each of the GETs is identified as EchelonGraph and carries a signed receipt you can verify at /verify-scan; a name resolution is a DNS query sent through our resolver, and it can carry neither. It is detect-only: it never registers or claims the resource, which is the actual takeover. Results are aggregate and host-redacted.

How do I fix a dangling subdomain?

Remove or update the DNS record the moment you decommission the resource it points to, audit your DNS for CNAMEs aimed at services you no longer own, and reclaim the target resource if it is still available before an attacker does.

Seeing this scanner in your logs? It's us. Our Discovery Radars name themselves — like Googlebot — in the User-Agent of every HTTP request they send, for example EchelonGraph-<Radar>/1.0 (+https://echelongraph.io/surface-scanner; opt-out https://echelongraph.io/responsible-disclosure; support@echelongraph.io) or, from our radar prober, EchelonGraphBot/1.0 (+https://echelongraph.io/bot), and their HTTP requests to the hosts they check also carry a From: support@echelongraph.io header. Some checks are a single identified GET; others send several requests to one host. Confirming an MCP endpoint sends a POST asking the server which protocol versions it supports, a second POST with the older handshake only if the first is refused without a 2026-07-28 error, a DELETE to close any session a POST opened and, if a POST is refused with HTTP 401 or 403, up to two GETs of the server's OAuth protected-resource metadata on the same host; where neither POST finds an MCP endpoint, the older SSE transport's stream is requested with GET, only its first event is read, and the connection is closed. A server that answers the first POST with a DiscoverResult, or with an error the 2026-07-28 revision defines, opens no session and is sent no further POST, so it is not written to; if the POST is refused with HTTP 401 or 403, the metadata GETs above still follow. Confirming an exposed datastore needs a protocol-level exchange, and on Redis our client names itself so the connection is identifiable in your own CLIENT LIST. We never log in, submit credentials or exploit what we find. Who we are, exactly what each check sends, and how to opt out → A radar's HTTP requests to the host it checks also carry a signed receipt you can validate at /verify-scan.