Subdomain takeover: how a forgotten CNAME ends up being yours
The story is always the same. Someone set up blog.yourcompany.com pointing with a CNAME at a Heroku app, or an S3 bucket, or GitHub Pages. Months later the service is decommissioned… but nobody deletes the DNS record. The target is now empty and claimable. An attacker registers that same name at the provider, and suddenly blog.yourcompany.com —a legitimate subdomain, with your brand and your HTTPS padlock— serves their content.
Why it hurts more than it looks
- Phishing from a real domain: the link really is
yourcompany.com. Not even the sharpest user suspects. - Cookie and session theft: if there are cookies scoped to
.yourcompany.com(Domain=), the hijacked subdomain can read them. - Bypassing allowlists: CSP, CORS or OAuth allowlists that trust
*.yourcompany.comnow trust the attacker. - Brand damage and, if it serves JS, execution in your domain's context.
The cause: "dangling" DNS records
A dangling record is a CNAME (or ALIAS/NS) pointing at a third-party resource that no longer exists or is no longer yours. The provider returns a recognizable error page —NoSuchBucket, There isn't a GitHub Pages site here, No such app— which is both the sign of the flaw and the invitation to claim it. Historically affected services: S3, GitHub Pages, Heroku, Azure (blob/cloudapp), Shopify, Fastly, Surge, Netlify, Zendesk… the list is long and alive.
How it's hunted (recon)
- Enumerate the target's subdomains: Certificate Transparency, passive DNS, dictionary brute force.
- Resolve each one and keep those with a CNAME to third-party services.
- Fingerprint the response: does it return one of those "unclaimed service" error pages?
- Confirm without exploiting: in a legit pentest or bug bounty, proving it is claimable is enough; do not publish content on someone else's domain beyond an agreed PoC.
How to close it (defense side)
- ✅ Inventory your DNS: every record must have an owner and a live service behind it.
- ✅ Correct decommission order: delete the DNS record first, then release the resource —never the other way around.
- ✅ Monitor Certificate Transparency and your own zones; alert on CNAMEs that resolve to "unclaimed" pages.
- ✅ Review forgotten subdomains periodically (campaigns, staging environments, acquisitions).
Checklist
- ✅ Do you have CNAMEs pointing at third-party services? Check them.
- ✅ When decommissioning: DNS first, resource after.
- ✅ Typical fingerprints:
NoSuchBucket, "There's nothing here", "No such app". - ✅ Watch out for
Domain=.yourcompany.comcookies and*.yourcompany.comallowlists. - ✅ Only against your own domains or with permission.
A subdomain takeover exploits no 0-day: it exploits forgetting. Your attack surface is not only what you deploy, it is also what you stop deploying and never clean up. A boring DNS inventory is the best defense against this quietly dangerous flaw.