Skip to main content
Back to Blog
Security

Subdomain Takeover: How to Find and Fix Dangling DNS Records

A forgotten CNAME to a deleted bucket or app lets a stranger serve content on your domain. How to find dangling DNS records and retire services safely.

PlatOps Team
Author
Published: October 29, 2026
9 min read

Every company that has shipped a marketing microsite, a status page, or a staging app on its own domain has created a DNS record pointing at someone else's platform: promo.example.com is a CNAME to an S3 bucket, help.example.com points at a SaaS help desk, app-old.example.com points at an Azure web app. Months later the campaign ends, someone deletes the bucket or the app, and nobody touches DNS. The record still points at a name on the provider's platform that no longer belongs to you.

That leftover record is a dangling DNS entry. If the provider lets anyone claim the name it points to, an attacker can create a resource with that exact name and serve their own content on your subdomain. Visitors see your domain in the address bar. That is a subdomain takeover, and it needs no stolen password and no software bug.

In June 2026 the AWS Customer Incident Response Team wrote that it has observed threat actors scanning for dangling DNS records. AWS and Azure have each shipped features that close the gap for new resources, but neither fixes the records already in your zone. Below: how to find them, the retirement order that prevents new ones, and the settings worth turning on.

TL;DR

  1. A subdomain takeover happens when your DNS points at a deleted cloud or SaaS resource whose name someone else can register; they then serve content on your domain.
  2. The fix order when retiring anything is fixed: delete the DNS record first, wait out its TTL, then delete the resource.
  3. Since March 2026, S3 buckets created in your account regional namespace can never be re-created by another account; you can require it with an SCP, but existing buckets stay in the global namespace.
  4. New Azure App Service apps created in the portal get secure unique default hostnames that outsiders cannot recreate; CLI, ARM, and Terraform deployments need an explicit setting.
  5. Domain verification records (asuid TXT on Azure, the _github-pages-challenge TXT on GitHub Pages) stop another tenant attaching your hostname even if a CNAME dangles.
  6. Checking whether a hostname resolves is not enough: once an attacker has claimed the name, it resolves fine. Check that you own the target.

How a takeover works

Microsoft's guidance on dangling DNS walks through the three steps:

  1. You create app-contogreat-dev-001.azurewebsites.net and a CNAME greatapp.contoso.com pointing at it.
  2. You delete the app but leave the CNAME.
  3. Someone else creates an app with the same name in their own subscription. Traffic for greatapp.contoso.com now reaches them.

The damage goes past a defaced page. Many web apps scope session cookies to the parent domain, so a page on any subdomain can read them. Microsoft notes the attacker can often get a valid TLS certificate for the hijacked name. A dangling MX record lets someone receive mail for that subdomain. And a phishing page on your real domain passes the "check the URL" advice every awareness training gives.

The risk depends on the provider. The community-maintained can-i-take-over-xyz list marks AWS S3 and Microsoft Azure "Vulnerable", Zendesk "Not vulnerable", and GitHub Pages, Heroku, Netlify, Shopify, and Webflow "Edge case". Its maintainers do not guarantee accuracy, so treat it as a starting point.

The records that dangle

CNAMEs to claimable cloud names

These are the classic case. AWS lists the services where the name in the CNAME can be re-registered by another account: S3 bucket names, Elastic Beanstalk environment names, and, in rarer cases, reissued CloudFront distribution names. EC2 instances, VPC resources, and private hosted zones are not affected, because they do not expose a name anyone can claim.

On Azure, Microsoft's detection tool covers App Service and its slots (azurewebsites.net), Blob Storage (blob.core.windows.net), Front Door (azurefd.net), CDN (azureedge.net), Traffic Manager (trafficmanager.net), API Management (azure-api.net), Container Instances, and public IP DNS labels (cloudapp.azure.com).

When an S3-backed CNAME dangles, the endpoint says so. We requested a bucket name that does not exist on 2026-10-29:

$ curl -s https://platops-example-retired-assets-8f3k2.s3.amazonaws.com/
<Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message>
<BucketName>platops-example-retired-assets-8f3k2</BucketName>...</Error>

A NoSuchBucket reply behind one of your hostnames is a finding: anyone can create that bucket name in the global namespace right now.

SaaS CNAMEs

Help desks, landing-page builders, and status pages all ask you to CNAME a subdomain to them, and the CNAME outlives the subscription. Whether a stranger can then attach your hostname depends on whether the vendor verifies domain ownership. GitHub Pages, for example, lets you verify a domain so other users cannot publish on it after you delete a repository or disable Pages. Verification covers immediate subdomains, and GitHub advises against wildcard DNS records because they leave deeper names open even when the domain is verified.

NS delegations

A delegated subdomain (dev.example.com NS ...) pointing at a DNS provider where the zone no longer exists is the worst version, because whoever recreates the zone controls every name under it. The same failure applies to whole domains: Infoblox and Eclypsium's Sitting Ducks research found registered domains delegated to DNS providers that hold no zone for them, estimated "over a million exploitable target domains on any given day", and counted over 35,000 domains hijacked this way since 2018. Their advice to domain owners: make sure every provider named in your delegation is one you have an active account with.

Finding dangling records

Start with an inventory of every record that points outside infrastructure you control. On Route 53, export the CNAMEs per hosted zone:

aws route53 list-resource-record-sets \
  --hosted-zone-id Z0123456789ABCDEFGHIJ \
  --query "ResourceRecordSets[?Type=='CNAME'].[Name, ResourceRecords[0].Value]" \
  --output text \
  | grep -E 's3[.-].*amazonaws\.com|elasticbeanstalk\.com|cloudfront\.net|azurewebsites\.net|blob\.core\.windows\.net|azurefd\.net|azureedge\.net|trafficmanager\.net|github\.io|herokudns\.com'

Repeat for NS records below the apex and for zones at other DNS providers. Where a host has no export, query names over DNS-over-HTTPS:

curl -s -H 'accept: application/dns-json' \
  'https://cloudflare-dns.com/dns-query?name=promo.example.com&type=CNAME'

Then, for each target, answer one question: does an account we control own this resource today? AWS is explicit that a resolution check is not enough, because "if an attacker has already claimed the resource, DNS resolution will succeed". Compare targets against your own resource inventory:

  • AWS: the sample-dangling-dns-detection reference solution from the same AWS post runs a custom AWS Config rule that matches Route 53 CNAMEs against S3, CloudFront, and Elastic Beanstalk resources recorded by AWS Config, and raises Security Hub findings. It can scan a whole organization through a Config aggregator. Third-party targets are out of its scope.
  • Azure: Microsoft's Get-DanglingDnsRecords PowerShell tool lists CNAMEs that point at Azure resources and checks them against your subscriptions through Azure Resource Graph; it accepts an input file for zones hosted elsewhere. Microsoft Defender for App Service also alerts when you decommission an app but leave its custom domain in DNS.
  • SaaS: confirm in each vendor's admin console that the hostname is attached to your account.

For anything you find, remove the record or point it at a resource you own, and treat it as a possible incident: if OAuth callbacks, API calls, or form posts went to that subdomain, assume whoever held it saw that data.

Retire services in the right order

Most dangling records come from teardown done in the wrong order. AWS states the rule in one line: "Always delete DNS first, wait for the TTL to expire, then delete the resource." Put it in the decommissioning checklist:

  1. Delete or repoint the DNS record.
  2. Wait at least the record's TTL so cached answers expire.
  3. Delete the bucket, app, distribution, or SaaS subscription.
  4. Confirm the name no longer resolves.

Make the link visible before teardown. Microsoft suggests delete locks on Azure resources that have a custom DNS entry, so whoever deletes the resource is reminded to remove the mapping first. If your DNS lives in Terraform next to the resource it points at, Terraform removes a record that references the resource before the resource itself, but it does not wait out the TTL. Split the teardown into two applies: the record first, the resource after the TTL has passed.

Platform settings that close the gap

S3 account regional namespaces

Since March 12, 2026, you can create S3 buckets in your account regional namespace. The bucket name ends with your account ID, Region, and -an, and AWS states these buckets "can never be re-created by another account". In CloudFormation:

BucketNamePrefix: 'marketing-assets'
BucketNamespace: "account-regional"

You can enforce it across an organization with a Service Control Policy:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "RequireAccountRegionalBucketCreation",
    "Effect": "Deny",
    "Action": "s3:CreateBucket",
    "Resource": "*",
    "Condition": {
      "StringNotEquals": { "s3:x-amz-bucket-namespace": "account-regional" }
    }
  }]
}

Two limits: the global namespace is still the default, and existing buckets cannot be migrated. Every bucket you created before adopting this is still re-creatable by anyone once deleted, so the retirement order above still applies to them.

Azure secure unique default hostnames

Azure App Service now generates default hostnames with a random hash and Region, such as contoso-a6gqaeashthkhkeu.eastus-01.azurewebsites.net, which no one outside your organization can recreate. It is generally available for Web Apps, Function Apps, and Logic Apps (Standard). Portal-created apps get it automatically; the CLI, ARM templates, and the REST API need an explicit opt-in on every create:

az webapp create --name contoso --resource-group rg-web \
  --plan plan-web --domain-name-scope TenantReuse

It cannot be applied to existing apps; Microsoft's migration path is to clone or restore into a new app. For apps on the old naming, add the asuid.<subdomain> TXT record with your domain verification ID, so no other subscription can validate your custom domain.

What CAA does not cover

CAA records, covered in our DNS security guide, limit which certificate authorities may issue for your domain, not which of their customers. If your CAA allows the CA a hosting platform uses, an attacker on that platform can still get a certificate.

Who owns this

Dangling records are an ownership problem more than a technical one. Marketing ordered the microsite, a contractor built it, IT holds the registrar login, and nobody's offboarding checklist includes DNS. A quarterly review of every record pointing outside your infrastructure, with a named owner for each, catches most of it, along with the stale mail records our post on DNS misconfigurations that hurt email deliverability describes.

If nobody on your team has the time, our Managed DNS service includes checking records against live servers and removing obsolete records when servers are retired.

Frequently asked questions

Is a subdomain takeover a vulnerability in AWS or Azure? No. AWS states the tactic does not leverage vulnerabilities of AWS services. The platform does what it was told; the leftover record in your zone sends visitors to whoever now holds the name. The providers' new features reduce how often a name can be reclaimed, but the record is the customer's to remove.

Does DNSSEC prevent subdomain takeover? No. DNSSEC proves that DNS answers came unaltered from your zone. In a takeover your zone answers correctly with the record you published; the problem is where that record points. DNSSEC protects against forged answers, not stale ones.

How often should we scan for dangling DNS records? Check as part of every teardown, and on a schedule as a safety net; the AWS reference solution evaluates every 24 hours by default. For a small business with a handful of zones, a quarterly review plus a decommissioning checklist that starts with DNS covers most of the risk.

Put this into practice

Book a free 1-hour call with a senior engineer about your infrastructure, or check your email security in 30 seconds.

Tags:dnssubdomain-takeoverdangling-dnssecurityawsazure

Get articles like this in your inbox

Practical security, infrastructure, and DevOps insights for teams in regulated industries. Published weekly.

Weekly digestUnsubscribe anytimeNo spam, ever

By subscribing, you agree to our Privacy Policy. Unsubscribe anytime.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Want to Discuss This Topic?

Schedule a call with our team to discuss how these concepts apply to your organization.

1 Hour

A focused conversation

Video or Phone

Your preferred format

No Sales Pitch

Honest, practical advice

Book a free 1-hour call