HTTPS, TLS, and the headers that protect your visitors

Your TLS cert is valid, but is it leaking hostnames, signed with a weak key, or living too long?

The padlock is a binary in most people's heads: there, or not there. The browser trusts the certificate, the connection is encrypted, done. But a certificate that passes the browser's trust check can still be telling a stranger things you didn't mean to publish, or resting on cryptography that's thinner than it should be.

These aren't the loud failures, the expired cert or the hostname mismatch that paint a full-screen warning. They're the quiet ones. The site works, the padlock shows, and the weakness is sitting in the cert's own fields, readable by anyone who connects, because a TLS certificate is a public document by design. Here are the three the scanner flags.

The cert's SAN list is a guest list, and yours might name the back rooms

Every certificate carries a Subject Alternative Name list: the set of hostnames the cert is valid for. When you request one cert to cover yoursite.com, www.yoursite.com, and api.yoursite.com, all three go in the SAN list. That's the cert working as intended.

The problem is the multi-domain SAN cert that quietly accumulated internal names. Someone issued one wildcard-ish cert to cover a batch of hosts, and the batch included staging.yoursite.com, admin.internal.yoursite.com, jenkins.corp.yoursite.com. Those names now travel inside a public certificate. Anyone who connects to the public site, or reads the Certificate Transparency logs where every issued cert is published, gets a list of your internal and pre-production hostnames for free. It's the same intel a forgotten staging subdomain hands over, except here you mailed it to them inside the cert that protects your front page.

request
openssl s_client -connect yoursite.com:443 \ | openssl x509 -noout -text
response
Subject: CN=yoursite.com
X509v3 Subject Alternative Name:
DNS:yoursite.com, DNS:www.yoursite.com,
DNS:staging.yoursite.com,
DNS:admin.internal.yoursite.com,
DNS:jenkins.corp.yoursite.com
The SAN list is part of the public cert. Every name in it is readable by anyone who connects, or who reads the CT logs.

The fix isn't to hide the names, you can't, they're public the moment the cert issues. It's to stop putting internal hostnames in a public cert. Give pre-production and internal hosts their own certificates (or a private CA), so a leak of one doesn't enumerate the rest, and so your public cert names only your public surface.

A 1024-bit key is a lock with a known weakness

A certificate's strength rests on the key it was issued for. For an RSA key, today's floor is 2048 bits; for an elliptic-curve key, 256 bits. Browsers stopped trusting 1024-bit RSA years ago, but the floor moves, and a cert minted long ago, renewed on autopilot against the original key, or generated by a script that defaulted to a small size, can still be running an undersized key that's valid but weak.

An undersized key doesn't break the connection. It weakens the math that the whole connection depends on: a smaller key is closer to being factorable, which is the thing TLS spends all its effort making infeasible. You don't get a warning for it the way you do for expiry, which is exactly why it lingers. The fix is to reissue the certificate against a fresh key of the right size, 2048-bit RSA at minimum (many now go 3072 or 4096), or a 256-bit EC key, and to make sure your renewal flow generates a new key rather than reusing the old one forever.

A cert valid for three years is one you can't quietly revoke

There used to be ten-year certs. Then the industry capped certificate lifetimes, and the cap keeps tightening, because a long-lived cert is a long-lived liability: if the key leaks, that cert stays trusted until it expires, and revocation is famously unreliable. The CA/Browser Forum baseline now caps publicly-trusted certs at 398 days, and the direction of travel is shorter still.

If your cert shows a validity window longer than that, either it predates the cap, or it was issued by an internal/private CA that doesn't follow the public rules. Neither is a breach. It's a signal that this cert can't be rotated out from under a problem quickly, that it's been sitting in place long enough to predate current norms, and that whatever workflow issued it isn't on the short-lived, auto-renewed cadence that modern TLS assumes. The cure for all three of these is the same thing that cures cert expiry: short-lived certs from an automated issuer (Let's Encrypt and friends issue 90-day certs and renew them for you), so your certificate is always fresh, always the right size, and never around long enough to become a problem.

# one big multi-year cert, RSA-1024, naming everything
Validity: 2023-01-01 to 2026-01-01   (1095 days)
Public-Key: RSA (1024 bit)
SAN: yoursite.com, staging.yoursite.com,
   admin.internal.yoursite.com, jenkins.corp...
Short-lived, auto-renewed certs scoped to your public names fix all three at once.

Reading it from outside

None of this needs access to your server. A certificate is handed to every client that connects, which means a stranger reads its SAN list, key size, and validity window the same way your browser does, by completing the TLS handshake and parsing the cert. That's exactly what SurfaceCheckr does: it pulls the leaf certificate your site presents, checks the SAN list for internal or non-production hostnames, reads the public-key size against the modern floor, and measures the validity window against the 398-day cap. It reads the cert you're already serving and stops there, no connection to your key, no probing your CA. The padlock told you the cert is trusted; these checks tell you whether it's also quietly oversharing. If an expired or mismatched cert is the failure you can see, the untrusted-cert states are the louder cousins, and knowing when yours expires is the one everyone learns the hard way.

Find it before someone else does.

Paste your domain. The grade and issue count are free, and you'll see in a couple of minutes exactly what's reachable from outside.