SecureBlockLog inStart a pentest
Vulnerability Repository
HighMisconfiguration

Subdomain Takeover

DNS records pointing to deprovisioned third-party services allow attackers to claim the service and serve content under the victim organization's subdomain.

CVSS 8.1CWE CWE-284OWASP A05:2021 — Security Misconfiguration

Description

Subdomain takeover (CWE-284 — Improper Access Control) is a vulnerability where a DNS record for an organization's subdomain continues to point to a third-party service (GitHub Pages, Heroku, Fastly, AWS Elastic Beanstalk, Azure, Netlify, S3, etc.) after the provisioned resource has been deleted or deprovisioned. An attacker who discovers this dangling DNS record can claim the service endpoint and serve arbitrary content from the organization's subdomain — with all the trust, cookies, and CORS permissions that domain carries.

This vulnerability is classified under A05:2021 — Security Misconfiguration because it results from operational negligence: DNS records are not cleaned up when services are deprovisioned. The impact significantly exceeds what a typical "misconfiguration" implies — subdomain takeover on a trusted subdomain can enable cookie theft (if the cookie is scoped to the parent domain), credential harvesting, phishing, CSP bypass, and OAuth redirect abuse.

Organizations with large numbers of subdomains and active use of SaaS platforms are most at risk. Engineering teams routinely create dev.example.com, staging.example.com, blog.example.com, and docs.example.com pointing to temporary deployments, then forget to remove the DNS records when the projects end.

How It Works

The classic lifecycle of a subdomain takeover:

  1. An engineer creates a GitHub Pages site for documentation at docs.example.com, configuring a CNAME record:

    docs.example.com. CNAME example-org.github.io.
    
  2. The GitHub Pages repository is later deleted or made private. The GitHub Pages endpoint example-org.github.io is now unclaimed — GitHub returns a "There isn't a GitHub Pages site here" page.

  3. An attacker discovers the dangling CNAME using automated tools:

    # subfinder discovers docs.example.com
    # nuclei tests for subdomain takeover
    nuclei -t ~/nuclei-templates/takeovers/ -target docs.example.com
    # [takeover] [http] [critical] docs.example.com — GitHub Pages — Vulnerable
    
  4. The attacker creates a new GitHub account, creates a repository named example-org.github.io (or the equivalent), configures it for GitHub Pages, and adds a CNAME file pointing to docs.example.com. GitHub Pages now serves the attacker's content at docs.example.com.

  5. The attacker hosts a convincing phishing page, a credential harvesting form, or malicious JavaScript at docs.example.com.

The attack extends beyond phishing. Because the attacker now controls a trusted subdomain:

  • Cookie theft — if authentication cookies are scoped to .example.com, the attacker's content at docs.example.com can read them via JavaScript.
  • CORS bypass — if example.com APIs trust *.example.com origins, the attacker can make credentialed API requests.
  • OAuth abuse — if docs.example.com was registered as an OAuth callback URL, the attacker can receive authorization codes.
  • CSP bypass — if the main site's CSP includes *.example.com, the attacker's subdomain can be used to load malicious scripts.

Common vulnerable services include: GitHub Pages, Heroku apps, Fastly CDN endpoints, AWS S3 website hosting, AWS Elastic Beanstalk, Azure Traffic Manager/Web Apps, Netlify, Vercel, Shopify, Zendesk, and many others. The can-i-take-over-xyz GitHub repository catalogs the vulnerability status of dozens of services.

Impact

  • Phishing at a trusted domain — victims receive phishing links from the organization's own domain, dramatically increasing the credibility and click-through rate.
  • Cookie theft — parent-domain-scoped cookies including session tokens are accessible to scripts on the taken-over subdomain.
  • Credential harvesting — a replica login page at the trusted subdomain captures real user credentials.
  • Malware distribution — the trusted domain reputation may not be flagged by security tools, enabling malware hosting.
  • OAuth token theft — attacker receives OAuth authorization codes for the compromised subdomain's registered redirect URIs.
  • Brand damage — the organization's domain name is directly associated with malicious content.

Detection

  1. Enumerate all subdomains — use subfinder, amass, assetfinder, or dnsx to discover all subdomains for the target organization. Certificate transparency logs (crt.sh) are an excellent passive source.
  2. Check for dangling DNS records — for each discovered subdomain, resolve the CNAME chain and check whether the final endpoint is claimed. Tools like subjack, subzy, and nuclei (with takeover templates) automate this:
    subfinder -d example.com -silent | httpx -silent | nuclei -t ~/nuclei-templates/takeovers/
    
  3. Manually verify candidates — for any subdomain that resolves to a service-specific error page ("No such app", "There isn't a GitHub Pages site here", "NoSuchBucket"), manually verify whether the endpoint is claimable.
  4. Check CNAME targets against known vulnerable services — compare CNAME targets against the can-i-take-over-xyz list to identify services with known takeover conditions.
  5. Monitor DNS records continuously — use a tool or service that alerts when a DNS record change creates a dangling condition — ideally as part of a continuous asset inventory program.

Remediation

Remove DNS records when deprovisioning services. The primary fix is process: before deleting a cloud resource, Heroku app, GitHub Pages repository, or any service with a custom domain, verify that the associated DNS records are removed. DNS cleanup must be part of the deprovisioning runbook.

Audit existing DNS records. Conduct a one-time audit of all DNS CNAME and A records. For each record pointing to a third-party service, verify the service resource still exists and is claimed.

Implement DNS monitoring. Use a continuous DNS monitoring service or tool that detects when a CNAME target returns a "claimable" error. Automate alerting on these conditions.

Avoid wildcard DNS records where unnecessary. Wildcard records (*.example.com) create takeover risk for any unclaimed subdomain that a service might issue. Use explicit records only.

Review cookie scoping. Audit all session and authentication cookies. Avoid setting Domain=.example.com (parent-domain scope) unless subdomains legitimately need cookie access — use Domain=app.example.com (origin-specific) instead.

Register OAuth redirect URIs carefully. Audit all OAuth callback URIs registered with identity providers. Remove registrations for deprovisioned subdomains promptly.

Ready when you are
Scope a pentest in the next two minutes.
Start scoping