How Certificate Transparency Logs Leak Internal Subdomains

Does Certificate Transparency leak internal hostnames? Yes, routinely. We read the public CT logs for 702 top domains through crt.sh, the same free lookup anyone can run, and found that 65.5% have logged at least one internal-looking hostname: a dev., staging., vpn., admin., jira., or vault.-style name that was almost certainly meant for staff, not the public internet. No host was scanned, resolved, or contacted to get this number. CT is a public, append-only log of every certificate a public CA has ever issued, and a name only has to receive one publicly trusted certificate to become a permanent, searchable record. This is an attacker's first move before any scanning starts, and most organizations are handing over their internal naming convention for free.
Why a public log leaks private-looking names
Certificate Transparency exists for a good reason: it stops a CA from quietly mis-issuing a certificate for a domain it should not, because every issued cert becomes visible to the domain owner and the public. Chrome and other browsers have required CT logging from publicly trusted CAs since 2018 under RFC 6962. That is a genuine security win for the ecosystem. The side effect is that CT also logs the hostname itself, and the hostname is often the most revealing part of the record.
Internal systems get public certificates for an ordinary, boring reason: nobody wants a browser warning when staff open the VPN portal or the internal Jira instance, even if DNS for that name resolves only on the corporate network or over a VPN tunnel. So the name gets a real certificate from Let's Encrypt, DigiCert, or another public CA, exactly like a public-facing site would. The certificate does its job quietly. The side effect is that vpn.example.com or staging-admin.example.com is now permanently readable by anyone who queries CT for example.com, through a free tool like crt.sh, with zero interaction with example.com's own infrastructure.
The data: what 702 top domains log
We queried crt.sh for a sample of the Tranco top-sites list (list 94Y82), one domain at a time with caching and backoff to be gentle on the service, and classified the first DNS label of every logged name against nine categories of conventional internal naming: remote access, auth/identity, non-production, devops/CI, internal collaboration, observability, admin/management, secrets/infrastructure, and explicitly-internal names. 702 of the 1,000 requested domains completed; 660 had any CT history at all. Per-domain results were held only in memory for the run and never written out, so nothing here names a specific organization. These are population percentages, not a list.
Non-production names dominate: 58.8% of domains have logged a dev., staging., test., or similar name. That is the least surprising finding and the least dangerous on its own, a staging environment being named is not a vulnerability. What is more interesting is how far down the list the dangerous categories run. 20.4% have logged a secrets or infrastructure-adjacent name like vault., consul., or k8s., and 21.8% have logged a remote-access name like vpn. or citrix. Those are the categories where the name itself tells an attacker exactly which product to go look for a known CVE against.
Individual prefixes tell the same story at finer resolution. Here are the twelve most common labels we matched, by share of the 702-domain sample:
| Prefix | Domains | Share of sample |
|---|---|---|
dev | 273 | 38.9% |
test | 260 | 37.0% |
staging | 192 | 27.4% |
admin | 145 | 20.7% |
stage | 131 | 18.7% |
auth | 125 | 17.8% |
qa | 114 | 16.2% |
demo | 94 | 13.4% |
internal | 90 | 12.8% |
vpn | 90 | 12.8% |
sandbox | 84 | 12.0% |
stg | 78 | 11.1% |
The vpn. prefix alone sits at 12.8% of the whole sample, which means roughly one in eight of the busiest domains on the internet has told the world, through a public log they never had to touch, that they run a specific remote-access product at a specific name. Combine that with the version-fingerprinting that is possible once a hostname resolves, and an attacker has gone from zero knowledge to a prioritized target list without sending a single packet at the target.
It rarely stops at one name
Leakage is not evenly spread across one name per domain. Of the 460 domains that leaked anything, 113 leaked a name from exactly one category, but the rest leaked across multiple categories at once: 65 domains hit three categories, 42 hit six, and 22 domains leaked a name in all nine categories we tracked. Once an organization is in the habit of giving internal tools real public certificates, the habit tends to be consistent across every internal tool they run, not just one. For an attacker, a domain that leaks broadly is more valuable than one that leaks a single name, because it maps out dev infrastructure, auth infrastructure, and admin infrastructure in one query.
How to check your own domain
This takes under a minute and needs no tool beyond a browser or curl, because you are reading the same public record we read.
- Query crt.sh directly. Open
https://crt.sh/?q=%25.yourdomain.com&output=jsonand read every hostname that comes back. That is everything CT has ever logged for your domain, including names issued years ago for servers that may be long decommissioned. - Grep the output for internal-looking labels. Look specifically for the prefixes in the table above: dev, test, staging, admin, auth, vpn, internal, vault, jenkins, gitlab, grafana, and their close variants. Anything that matches is permanently public, whether or not it currently resolves.
- Treat every match as already known to an attacker. You cannot retroactively un-log a certificate. The only move is to assume the name is public, make sure the service behind it does not rely on obscurity, and keep it patched and access-controlled like an internet-facing asset, because to an attacker reading CT, it already is one.
What this does not prove
Honest limits, because a number without its caveats is marketing.
- A logged name is not proof of a live, reachable, or vulnerable service. We matched hostname text in CT, nothing else. We did not resolve any name, connect to any host, or test whether the service behind it still exists. Some of these names point at decommissioned infrastructure; some point at nothing at all.
- It is a 702-domain sample, not the whole internet. Tranco's top sites skew toward large, established organizations with enough infrastructure to have dev and staging environments in the first place. A different ranking methodology or a broader sample would shift the exact percentages.
- It is a snapshot. These figures describe CT's state as of our 24 July 2026 read. Organizations add and retire internal hostnames continuously, so the exact figures drift over time even if the underlying behavior does not.
- Prefix matching is heuristic, not certain. A label like
adminis usually an internal admin panel, but it can occasionally be a legitimate public-facing product name. We optimized the category list for conventional naming, not perfect precision, so treat the percentages as a strong signal, not an exact inventory. - This measures exposure of a name, not exploitability. Knowing that
vpn.example.comexists is reconnaissance, not compromise. What it buys an attacker is a prioritized, low-effort list of what to go look at next.
Frequently asked questions
Can attackers use Certificate Transparency logs to find subdomains?
Yes. Every certificate a public CA issues is logged under RFC 6962, and anyone can search those logs for free through crt.sh. In our 702-domain sample, 65.5% of organizations had logged at least one internal-looking hostname this way, with zero interaction with their infrastructure.
Can CT logs reveal internal hostnames that were never meant to be public?
Yes. A name only needs one publicly trusted certificate, often issued so staff do not see a browser warning, to become a permanent public record. The server behind it does not need to be internet-reachable for the name itself to leak.
What information gets exposed in a certificate's Subject Alternative Name field?
The SAN field lists every hostname a certificate covers. A single multi-domain certificate can expose dozens of names at once, all searchable in CT the moment the certificate is issued.
How do I discover subdomains using crt.sh?
Query https://crt.sh/?q=%25.yourdomain.com&output=json. It returns every logged certificate for your domain and its subdomains, including ones issued for servers that may no longer exist. It is a passive, read-only lookup of a public log, the same method we used here.
Does a wildcard certificate stop subdomains from appearing in CT logs?
A wildcard cert for *.example.com logs only the wildcard string, hiding the specific subdomain label. But the moment one service gets its own uniquely named certificate, that name is logged even if everything else sits behind a wildcard.
How can I prevent internal hostnames from leaking into Certificate Transparency?
Use a private, internal CA for names that should never be public, since only public CAs must log to CT. Prefer wildcard certificates over uniquely named leaf certificates where your architecture allows it, and treat anything already in CT as permanently known.
Are private or internal certificate authorities exempt from Certificate Transparency logging?
Yes. CT logging is required of publicly trusted CAs, not of certificates in general. A certificate from your own internal CA, trusted only by your managed devices, never has to touch a public CT log.
Related reading
- What can attackers actually see about your company? The broader attack-surface question this post answers one slice of.
- How long does it take a certificate to show up in CT? Same crt.sh wheelhouse, the timing question instead of the naming question.
- Is Certificate Transparency already post-quantum? A different layer of the same public-log ecosystem, the checkpoint-signing layer instead of certificate content.