Logo run_as_root - Magento B2B Agency Würzburg
SECURITY

Dangling CNAMEs and Subdomain Takeover: The DNS Ghosts Haunting Old Magento Stores

When you migrate off Hypernode or Hipex, decommissioned CNAMEs stay in your DNS. How that becomes a subdomain takeover, and how to audit your zone for it.


On this page

    A merchant moves off Hypernode to a new hosting vendor. The move takes a weekend. The merchant's agency changes the A record on the apex domain, confirms the store is up, closes the ticket. Six months later, an attacker runs amass or a subdomain-enumeration scanner against the merchant's zone, finds a staging.merchantstore.com still pointing at merchantstore.hypernode.io, signs up for a free Hypernode account, claims the hostname, and serves their own content from it. Nothing exotic happens. The attacker didn't break any security boundary. The DNS and the cloud vendor did exactly what they were told.

    This is subdomain takeover. Magento stores acquire it disproportionately because Magento-hosting vendors use the same CNAME patterns: yourstore.hypernode.io, yourstore.hipex-cloud.com, a Cloudways-flavoured variant. When you migrate, the A and MX records on the apex get updated. The subdomain CNAMEs usually don't.

    TL;DR

    • Subdomain takeover = your DNS points subdomain.yourstore.com at a cloud-hosted name you no longer own. Someone else can claim that cloud-hosted name and put content on your subdomain.
    • The main Magento-specific cause: hosting migrations. Hypernode, Hipex, Cloudways, Sonassi, and a handful of other Magento specialists use predictable CNAME patterns. When you leave, the CNAMEs stay.
    • The audit is cheap. Enumerate every subdomain, dig each CNAME, curl each target. Any target returning an "unclaimed hostname" error page is a takeover risk.
    • The adjacent pattern to look for: TXT records named __backup__ or old_ip_ that document your historical origin IP. Those leak origin info attackers use to bypass your Cloudflare proxy.
    • When you find one: delete the DNS record first, then decide whether to reclaim the hostname or leave it dead. Reclaiming only makes sense if you'll use the subdomain again.

    What subdomain takeover actually is

    Your domain has a DNS zone with records. A few of those records are CNAME entries: staging.merchantstore.com points to merchantstore.hypernode.io, say. The CNAME target is a hostname managed by a cloud vendor. The cloud vendor owns the TLS, the routing, and the content for that hostname, on your behalf, while your account with them is active.

    When you leave the vendor, they decommission your hostname. The CNAME in your DNS still points at it. Anyone can now sign up with the same vendor, claim the same hostname (if the vendor allows it, and most do), and their content will be served at your subdomain. The browser trust chain treats it as your site: same apex domain, same DNS-verified CNAME target, valid TLS certificate from the vendor's wildcard or issued cert. Cookies scoped to .merchantstore.com can be read. HSTS configured with includeSubDomains gives the attacker free TLS.

    It's not a hack in the Hollywood sense. It's a vendor-management issue that expresses as a security one. The fix is also vendor-management: clean up your DNS when you leave.

    Why this happens disproportionately on Magento-hosting migrations

    Three things conspire.

    Magento-specialist hosting uses predictable CNAMEs. Hypernode's yourstore.hypernode.io, Hipex's yourstore.hipex-cloud.com, Cloudways' multiple flavours. They're easy to enumerate. A subdomain scanner looking for takeover targets doesn't have to be clever; it can just walk every major Magento vendor's hostname pattern against your zone.

    Migrations are weekend work. They happen under time pressure, with a small team, and success is measured as "the store is up and taking orders". Nobody's DNS audit task comes off the backlog during the migration sprint; it comes off the backlog six months later, after a security audit catches it.

    Magento stores tend to have many subdomains. checkout., images., cdn., ftp., mail., stage., dev., preview., m., www2., plus whichever marketing subdomains the CMO set up two agencies ago. Each one is a DNS record. Each one is a potential takeover target. Moving hosts updates the apex; the long tail of subdomains is where the misses hide.

    ⚠️
    Even subdomains you think are harmless can bite you. An attacker claiming staging.merchantstore.com can set a cookie scoped to .merchantstore.com that your main store's JavaScript will happily read. They can serve a login form that looks like your login, on your real domain, with a valid certificate. Phishing campaigns love this pattern because it survives most URL-based security training.

    The audit: enumerate, dig, curl

    The audit is three steps, runnable in any shell with dig and curl.

    Step 1: enumerate every subdomain in your zone.

    Your DNS vendor (Cloudflare, Route 53, Gandi, whoever) has an export button. Use it. Grab the raw zone file and extract A and CNAME records. If the export isn't available (or the zone is hand-managed somewhere), pair it with an external subdomain scan (amass, subfinder, crt.sh lookup against your certificate transparency logs) to catch subdomains you forgot you had. The certificate-transparency lookup is free and usually finds entries the internal zone dump misses.

    Step 2: dig each CNAME target and classify.

    1# Example: bulk dig every subdomain from a file of hostnames.
    2while read sub; do
    3 target=$(dig +short CNAME "$sub" | sed 's/\.$//')
    4 echo "$sub -> ${target:-A-RECORD}"
    5done < subdomains.txt

    Look for CNAMEs pointing at Magento-specialist hosting vendors (*.hypernode.io, *.hipex-cloud.com, *.cloudways.com, *.sonassi.net) or generic cloud vendors you no longer have active accounts with (*.herokuapp.com, *.s3.amazonaws.com, *.azurewebsites.net, *.github.io). Also flag any CNAME whose target domain is something you don't immediately recognise.

    Step 3: curl each candidate target and check for takeover signatures.

    1# The "does this cloud vendor's hostname currently serve someone's content?" check.
    2curl -sI "https://yourstore.hypernode.io" | head -5
    3curl -sI "https://old.yourstore.com" | head -5

    Each cloud vendor has a distinctive error page when a hostname is unclaimed. Hypernode, for example, returns a specific branded "not found" page. GitHub Pages returns "There isn't a GitHub Pages site here." Heroku returns the Heroku "No such app" page. The GitHub-maintained can-i-take-over-xyz repository is the canonical catalogue of takeover signatures per vendor; consult it before acting on any finding.

    Any CNAME whose target returns a vendor's unclaimed-hostname response is a takeover risk. Any CNAME whose target returns NXDOMAIN is also a risk (the attacker just has to claim the name).

    The __backup__ TXT record anti-pattern

    While you're in the zone, check for TXT records with names like __backup__, _old_ip, origin_ip, or any variant that looks like a dev left themselves a note about the historical origin. They're usually added during a migration for rollback convenience and never removed.

    The problem: an attacker doing reconnaissance against your zone harvests these TXT records and now knows your real origin IP. If you're behind Cloudflare, the whole point of Cloudflare is to hide the origin IP so attacks have to come through the CDN. A TXT record publishing the origin directly defeats that. The attacker can then probe the origin on port 443 and 80 without going through Cloudflare at all, bypassing your WAF, your rate limits, your firewall rules, everything.

    These records are easy to find and should be deleted on sight. If a team needs to remember historical infrastructure for rollback, that information belongs in a runbook, not in a public DNS zone.

    What to do when you find one

    Three steps, in this order.

    First, remove the DNS record. This is the lowest-risk, highest-impact action. The subdomain stops pointing at anything; the takeover window closes immediately. Everything else is cleanup. If you're nervous about removing a record "in case someone was using that subdomain", grep your codebase, your Cloudflare logs, your analytics for any traffic to the subdomain in the last 90 days. If there's none, it's gone.

    Second, decide whether to reclaim the hostname. If you'll use the subdomain again soon, reclaim the cloud-vendor hostname to hold it for yourself. If you won't, don't; reclaiming a dead subdomain just starts a billing relationship you'll forget about and creates the same problem in two years.

    Third, set up zone monitoring. There are hosted services (DNSDumpster alerting, Detectify, hand-rolled scripts) that re-enumerate your subdomains on a schedule and alert you on new CNAME targets or NXDOMAIN responses. Budget for one, configure it once, leave it running. The next time a dev spins up a subdomain for a two-week project, you'll know about it.

    The dangling-CNAME audit checklist

    1. Export the full DNS zone

      Dump every A, AAAA, CNAME, and TXT record from your DNS vendor's zone editor. Keep a copy in source control alongside infra-as-code. The zone should never be larger than what you can read in one sitting.

    2. Enumerate beyond the zone

      Run amass, subfinder, or a crt.sh lookup to find subdomains that appear in certificate-transparency logs but not in your zone dump. Legacy subdomains that were migrated away from often still have old certs and will show up here.

    3. dig every CNAME target and classify

      Any CNAME whose target domain is not currently hosting your content is a candidate for audit. Flag Magento-specialist hosts (Hypernode, Hipex, Cloudways, Sonassi) first, then generic clouds (Heroku, S3, Azure, GitHub Pages) second.

    4. curl each candidate and check for vendor takeover signatures

      Compare the response to the can-i-take-over-xyz catalogue. An unclaimed-hostname banner from the vendor is an immediate takeover risk. NXDOMAIN targets are also at risk, slightly lower priority.

    5. Delete first, decide later

      Removing a dangling CNAME closes the takeover window. Decide reclaim-vs-leave-dead after the record is out of DNS, not before.

    6. Delete __backup__ and origin_ip TXT records

      Grep the zone for TXT records whose name or value looks like documentation of historical infrastructure. Each one is a Cloudflare-bypass gift to anyone enumerating your zone.

    7. Stand up ongoing zone monitoring

      DNSDumpster alerting, Detectify, or a hand-rolled cron that re-dumps your zone and diffs against source control. Alerts on new CNAME targets or changed TXT records land in the same channel as other security alerts.

    8. Run the audit after every hosting migration

      The entire finding set in this article is introduced by hosting changes. Add a mandatory DNS audit to every migration runbook, scheduled one week after the migration completes.

    Hosting migrations leave DNS ghosts. We find them.

    We run focused Magento 2 infrastructure audits that include a full DNS-zone walk, subdomain enumeration, and takeover triage. You get the ghost list, the recommended fix per record, and rule-change diffs. Two days. Straight to your zone editor.

    Book an infrastructure audit