Abstract
On August 27, Google sent us an email. “New owner for https://dev-docs.trackjs.com/.” Some jerk at sportyplex.com had verified ownership of one of our old hostnames in Search Console, and Google wanted to know if we recognized them.
We did not.
We barely recognized the hostname. None of us had thought about dev-docs.trackjs.com in about ten years.
What was at dev-docs.trackjs.com
Around 2013, when TrackJS was new, we rented a DigitalOcean droplet to build our first documentation site. dev-docs.trackjs.com was the development copy. It was never linked from anywhere. It was never meant to be seen by anyone but us.
The docs eventually moved to GitHub. The droplet was destroyed. The IP address went back to DigitalOcean’s pool. But the A record for dev-docs.trackjs.com stayed in our DNS, pointing at an address we no longer owned.
Nobody deleted it. We have better things to worry about. When you decommission a server, you shut it down, you stop paying for it, and you move on. Every company that has been around for more than a few years has dangling DNS records like this.
How our dangling DNS record became a subdomain takeover
A dangling DNS record is a name that still resolves to an address, but you don’t control the address anymore. The attack built on it is called a subdomain takeover, or subdomain hijacking. You don’t break into anything. You just stand where the record points and wait for the name to arrive.
Cloud IP addresses are recycled constantly. Researchers at Penn State measured this on AWS and found 5,446 domains whose DNS still pointed at addresses they had been handed. Twenty-three of those domains were in the top 1,000 sites on the internet. Traffic meant for those domains, including credentials and API calls, arrived at servers the researchers controlled.
In July, Silent Push published research they called Danglegeddon. They found 16,000 dangling subdomains, and successfully simulated takeovers of 4,000 of them. They used AI to write the tooling and reported having “a fully developed takeover script to mass-exploit all vulnerable domains” within hours. The targets in their simulation included a US federal agency, a global bank, and a Fortune 500 manufacturer.
Somebody followed that playbook and found dev-docs.trackjs.com pointing at an address they could get.
Nobody hacked our DNS. DNS hijacking, where an attacker changes your records, is a different attack with different defenses. Our records were fine. We wrote the address into the zone ourselves, ten years ago.
The certificate was the easy part
Once they had a server at the address, they needed a TLS certificate for it so browsers could visit and Google would index it.
Getting a certificate is easy. The HTTP-01 challenge in ACME has the CA connect to the hostname on port 80, ask for a specific file, and issue the certificate. The hostname resolved to their server. Their server answered. Let’s Encrypt issued them a 90-day certificate for dev-docs.trackjs.com.
The CA did nothing wrong. Domain validation is designed to trust whoever answers at the address the domain points to. That is the entire model of the public web PKI, and it means the security of your certificates depends on the hygiene of your DNS. A forgotten A record is a standing offer to issue certificates in your name to whoever collects the address.
What they did with it
They put up a Japanese celebrity gossip site. Even the attacks against us are kinda cool.
This is a well known pattern. Google calls it the Japanese keyword hack: take an established domain, fill a corner of it with thousands of spam pages, and ride the domain’s reputation into search results. Google’s own guidance notes that “the hacker will typically add themselves as a property owner in Search Console.”
That is exactly what they did, and that’s how we found it.
SEO spam was the lucky outcome. If that hostname were more important than dev-docs, it could be used for more nefarious things like phishing, scraping cookies, or receiving sensitive data. But that sort of attacker wouldn’t have registered with Google Search Console.
What would have caught it
We found the A record, deleted it, and took the Search Console property back from them. We fixed it in twenty minutes. But how we found it bothers me. Google had to tell us.
We build a certificate transparency search tool. Every public certificate issued ends up in our database. The certificate for dev-docs.trackjs.com was in our own tool, from the moment it was issued. Nobody looked, because who looks at a search page every day?
The banner at the top of that page read “Coming Soon! Get alerts whenever new certificates are issued for domains you care about.” We knew we needed alerting for this, but we just hadn’t gotten to it yet. Doh.
Here are three things you should do to prevent this:
1. Check for dangling DNS records
You probably won’t do this. It’s a boring, manual process. The Danglegeddon research showed nobody does it, and I can confirm we didn’t. A more practical version is a periodic audit to pull every A and CNAME record in your zones, and resolve them. Anything that’s abandoned is a name you are offering to strangers.
2. Set up CAA records
Set CAA records in your DNS for which CAs are allowed to issue for your domain. The common CAA record almost everyone sets up only names a CA: 0 issue "letsencrypt.org". Over 99% of CAA records only do this.
But that CAA record wouldn’t have helped us, because we use Let’s Encrypt and so did the spammers.
RFC 8657 extends CAA so the record can name the specific ACME account and validation method that are allowed to issue. With this in place, Let’s Encrypt would have refused their request even though it was the same CA we use:
example.com. IN CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/<your-account-id>; validationmethods=dns-01"
Let’s Encrypt honors these today. Most other CAs don’t yet, but every public CA is required to by March 2027. It costs nothing to set the record now.
3. Watch the CT log
Watch for certificates for your domain that you didn’t request. That’s the alert we hadn’t finished back in August, but it’s ready now. CertKit watches the certificate transparency logs for the domains you tell it to, sends a weekly summary of everything issued, and notifies you the moment a certificate appears for a subdomain it has never seen before.
We needed it, so we built it.
CAA checking, including whether your records use the account binding above, is on the roadmap soon.
CertKit watches the certificate transparency logs for your domains, so the next certificate you didn’t ask for is not a surprise.