Back to Blog
Deep DiveFebruary 1, 20268 min read

Subdomain Takeover: How Attackers Exploit Dangling DNS Records

A technical deep-dive into subdomain takeover — how dangling CNAME records create takeable endpoints, how attackers claim them, and how automated EASM detection prevents this class of vulnerability.

Subdomain takeover is one of the most underappreciated vulnerabilities in the external attack surface. It requires no exploitation skill to execute, it's trivially automatable, and organizations create the conditions for it themselves — every time they deprovision a cloud service without cleaning up DNS.

What Is Subdomain Takeover?

When you deploy a service to a third-party platform (GitHub Pages, Heroku, AWS Elastic Beanstalk, Azure CDN, Fastly, etc.), you typically create a CNAME record pointing your subdomain to the platform's infrastructure:

staging.yourcompany.com  →  CNAME  →  yourcompany.eu.ngrok.io

When you decommission that service, you delete the Heroku/GitHub/Azure resource. But if you forget to delete the CNAME record, the subdomain now points to an unclaimed resource name on a third-party platform.

An attacker can register that resource name and immediately receive traffic from your subdomain.

The Attack in Practice

1. Attacker scans your subdomains
2. Finds: staging.yourcompany.com → your-old-app.herokuapp.com
3. Checks if "your-old-app" is available on Heroku
4. Registers "your-old-app" on Heroku (free tier, takes 2 minutes)
5. Deploys content to the app
6. staging.yourcompany.com now serves attacker content

The attacker now controls a page on your domain. They can:

The TLS certificate point is critical: attackers can get a valid, browser-trusted HTTPS certificate for your subdomain. The padlock icon will show. Users have no way to distinguish this from legitimate content.

Vulnerable Services — Common CNAME Targets

Services where resource names are re-claimable:

ServiceCNAME PatternClaimable?
GitHub Pages*.github.ioYes
Heroku*.herokuapp.comYes
Netlify*.netlify.appYes
AWS Elastic Beanstalk*.elasticbeanstalk.comYes
Azure CDN*.azureedge.netYes
Fastly*.fastly.netYes
Shopify*.myshopify.comYes
Zendesk*.zendesk.comYes

The canonical resource for testing: can-i-take-over-xyz (GitHub repository listing hundreds of vulnerable services with detection fingerprints).

Detection: What to Look For

A subdomain is vulnerable to takeover when:

  1. A CNAME record exists pointing to a third-party service
  2. The target resource at that service returns a "resource not found" or "no such app" response
  3. The resource name at the third-party service is available for registration

The key detection signal is the third-party error page fingerprint. Each service returns a distinctive response when pointing to an unclaimed resource:

GitHub Pages:    "There isn't a GitHub Pages site here."
Heroku:          "No such app"
Netlify:         "Not Found - Request ID: ..."
Fastly:          "Fastly error: unknown domain ..."
AWS/EB:          NXDOMAIN or 404 from AWS

An EASM tool that crawls your subdomains and checks for these fingerprints will surface takeover candidates immediately.

The Scale of the Problem

Organizations consistently underestimate how many stale CNAME records they have. Factors that create dangling CNAMEs:

For a company of 200+ engineers that's been shipping for 3+ years, 10–30 vulnerable subdomains is typical. One actively exploited takeover is a brand crisis.

Remediation

For each confirmed takeover candidate:

Step 1: Delete the CNAME record immediately. DNS propagation takes up to 48 hours; do not wait for it.

Step 2: Verify the target resource is truly deprovisioned. If the CNAME is dangling but the resource still exists (perhaps renamed), understand why before deleting.

Step 3: Add the subdomain to your EASM monitoring scope with an alert on re-appearance.

Preventive measure: Implement a process where DNS record deletion is part of service deprovisioning checklists. Infrastructure-as-code (Terraform, Pulumi) that manages both cloud resources and DNS simultaneously eliminates the manual gap.

Prevention in IaC

If you use Terraform, colocate your DNS and cloud resources in the same module:

resource "heroku_app" "staging" {
  name = "yourcompany-staging"
}

resource "cloudflare_record" "staging" {
  zone_id = var.zone_id
  name    = "staging"
  value   = heroku_app.staging.web_url
  type    = "CNAME"
  # Deleting the heroku_app will also delete this record
  # because they're managed together
}

When terraform destroy runs on the Heroku app, it also removes the DNS record. The dangling state never exists.

Continuous Monitoring Is the Only Scalable Defense

Manual DNS audits catch what you find at the moment you look. EASM continuous monitoring catches:

PentestCheck monitors your full subdomain inventory daily and alerts on any new dangling CNAME with a service fingerprint match. Takeover candidates surface within hours of becoming vulnerable — before an attacker finds them first.


PentestCheck EASM Engine continuously monitors your DNS records and fingerprints third-party service responses. Takeover candidates are flagged as HIGH severity with remediation instructions.

Scan your attack surface today

Free plan includes 3 targets and 10 scans/month. No credit card required.

Start Free Scan