Certificate Transparency Logs: How Every Subdomain You Own Becomes Public Record
How CT logs expose every subdomain via crt.sh, crt.name, subfinder, and amass — and how to use the same technique to defend your own domains.
Long Nguyen
Founder · System Architect
What Certificate Transparency logs actually are
Every publicly trusted TLS certificate issued today has to be published to a Certificate Transparency (CT) log before browsers will accept it without a warning. Chrome has enforced this since 2018; Apple's platforms enforce it too. The logs are append-only Merkle trees run by companies like Let's Encrypt (Sunlight), Google (Argon), Cloudflare (Raio), DigiCert, and Sectigo. A CA cannot quietly issue a certificate for staging.yourcompany.com and keep it off the public record — the Signed Certificate Timestamp browsers require is proof the cert already sits in one of these logs.
CT was built to catch mis-issued and fraudulent certificates, not to be a subdomain directory. But the side effect is permanent: the SAN (Subject Alternative Name) field of every certificate is public, and that field lists every hostname the cert covers. A wildcard cert for *.yourcompany.com or a SAN cert covering five internal tools puts all five hostnames on the record forever, whether or not any of them ever appear in public DNS, a sitemap, or a Google search result.
That's the part people underestimate. Keeping a subdomain out of DNS zone transfers or off your public site doesn't keep it out of CT logs — if it ever had HTTPS, it's logged. Dev environments, admin panels, internal APIs, third-party integration endpoints: if someone requested a cert for it, it's there.
How to query CT logs for a domain, manually
crt.sh, run by Sectigo, is the interface most people reach for first. A browser query looks like https://crt.sh/?q=%.example.com, and it also exposes a JSON endpoint for scripting:
curl -s "https://crt.sh/?q=%.example.com&output=json" | jq -r '.[].name_value' | sort -u
That one-liner is the fastest way to get a raw subdomain list from the command line — no signup, no API key, no DNS brute force. crt.name covers the same ground but with an API-first design: GET https://crt.name/v1/search?apex=example.com returns a flat list of every subdomain the index has on file, built by parsing SAN fields out of live Static CT and legacy RFC 6962 log entries as they land, then backfilling older names from replayed logs, Common Crawl, and zone-file sources. The upside over crt.sh for automation: no HTML to scrape, no rate-limit surprises on a plain GET.
Run either query against a large domain and you'll notice something immediately: the list includes certificates issued a decade ago for services that no longer exist. CT logs are append-only — nothing is ever removed, so a query returns history, not just what's currently live. That's useful for recon and occasionally embarrassing for the domain owner.
crt.sh vs crt.name vs subfinder vs amass: which one to reach for
These tools aren't really competing with each other — they sit at different points on the speed-vs-coverage curve, and a real engagement usually uses more than one.
| Tool | What it's best at | Data source | When to use it |
|---|---|---|---|
| crt.sh | Fast manual lookup in a browser | CT logs only, scraped/indexed by Sectigo | One-off check on a single domain |
| crt.name | Scripting and bulk queries | CT logs (live + replayed) plus Common Crawl, CZDS, Chaos, DNS blocklists | Automated pipelines, no API key required |
| subfinder | Fast breadth across many passive sources at once | Aggregates crt.sh, Censys, Cert Spotter, and dozens more | First pass on a new target |
| amass | Maximum coverage, including active techniques | CT logs plus DNS brute force, scraping, API integrations | When you need the deepest possible asset inventory |
| Censys / Cert Spotter | Enrichment and real-time cert monitoring | CT logs plus IP/service scan data | Ongoing monitoring of your own certs, or deeper pivoting on a target |
For a quick gut-check on a domain, crt.sh or crt.name is enough. For a real attack-surface mapping exercise — the kind you'd run before an agent-readiness or security review — start with subfinder for speed, then run amass if the target is large enough that missed subdomains matter.
What this list is actually used for
A subdomain list on its own isn't a breach. What it changes is the attacker's starting point: instead of guessing at your infrastructure, they get a name-based inventory and go straight to targeted work.
- Finding the soft targets first.
admin.,staging.,internal-api., andvpn.subdomains tend to run older software, weaker auth, or default configs, because "nobody knows the URL" was the whole security model. - Subdomain takeover. If a CT-logged subdomain still resolves via CNAME to a decommissioned cloud service (an old S3 bucket, a deleted Heroku app, a expired third-party SaaS), an attacker can often claim that resource and serve content from your subdomain — with your cert history and your domain's trust.
- Phishing that looks legitimate. A list of real internal-sounding hostnames makes a spoofed login page or a spear-phishing email far more convincing than a generic guess.
- Prioritizing vulnerability scans. Every discovered hostname is one more entry point to fingerprint and probe — CT logs turn passive recon into a target list with zero packets sent to you.
Turning the same technique into defense
You can't stop your certs from being logged, and you shouldn't want to — CT is what makes it possible to catch a fraudulently issued cert for your domain in the first place. The move is to monitor the same feed the attackers query, so you see new subdomains and new certs before someone else does.
- Baseline your current subdomains. Run a crt.sh or crt.name query against every apex domain you own and treat the output as your real asset inventory, not the one in your internal wiki.
- Check for dangling DNS records. For every subdomain that shows up in CT but isn't in active use, verify whether its DNS record still points somewhere — a forgotten CNAME to a deprovisioned service is a takeover waiting to happen.
- Set up recurring monitoring. Cert Spotter and several CT-log aggregators support alerting on new certificates for a domain. A scheduled
crt.shorcrt.namequery in a cron job works too if you want zero third-party dependency. - Decommission cleanly. When you retire a subdomain, remove the DNS record, not just the app behind it. The cert will stay in CT logs forever either way, but a dead DNS record pointing nowhere is a dead end for an attacker instead of an open door.
This is the same passive-recon groundwork we run before hardening a client's public-facing infrastructure — pairing CT-log discovery with the DNS and crawler-facing work covered in our custom software and security hardening service catches orphaned subdomains before they become the entry point.