The files you forgot you deployed

Is your TLS private key downloadable? (It's the one file that undoes HTTPS)

Your TLS certificate has two halves. The certificate itself is public, every visitor receives it, it's meant to be seen. The private key is the other half, and it's the secret the entire padlock depends on. It's what proves that the server answering for yoursite.com is genuinely yours and not an impostor. The certificate says "I am yoursite.com"; the private key is the only thing that can prove it.

So the worst possible place for that key to be is downloadable from the website it protects. And it ends up there more often than you'd think, sitting at /server.key, /privkey.pem, /private.pem, or /key.pem, one GET request away from anyone.

What the key is, and what holding it means

A TLS handshake works because the server can do something with the private key that nobody without the key can do. That's the whole mechanism: possession of the private key is proof of identity. The browser checks that the certificate is trusted, then checks that the server actually holds the matching private key. Pass both, padlock.

If a stranger has your private key, they can pass that second check too. Now they can stand up a server, present your real, trusted certificate, complete the handshake correctly, and a browser will show the padlock for a site that isn't yours. Combined with any position on the network, a malicious Wi-Fi access point, a compromised router, a DNS trick, they can intercept traffic meant for you and the victim's browser sees nothing wrong, because nothing is wrong as far as TLS can tell. The key that was supposed to prove you're you now proves they're you.

request
GET /privkey.pem HTTP/1.1 Host: yoursite.com
response
HTTP/1.1 200 OK
Content-Type: application/octet-stream
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSj...
...the full private half of your certificate...
-----END PRIVATE KEY-----
A 200 with a PEM body is the whole game. The cert is public; this is the secret it was paired with.

How a private key lands in the web root

It's almost always a copy that escaped, not the key your server is actually using. You generated a cert, the .key and .pem files landed in the project folder next to everything else, and the project folder is what got deployed. Or you were debugging a TLS setup, dropped the key somewhere convenient "just to test," and never cleaned it up. Or a backup or migration script wrote the cert bundle into a directory the web server happily serves.

The web server doesn't know privkey.pem is special. It's a file in a directory it's configured to serve, so it serves it, with a 200 and the raw bytes, to whoever asks. The scanner only flags this when the response body is a genuine PEM private key, the -----BEGIN ... PRIVATE KEY----- block with a real base64 body, not a stray file that merely has the name. That gate matters, because a soft-404 page or a placeholder won't trip it; a real downloadable key will.

This is a reissue, not just a delete

Here's what makes a leaked private key different from most exposed files. Deleting the file doesn't fix it. If the key was downloadable for any length of time, you have to assume it's been copied, and a copied private key stays valid until the certificate it belongs to is revoked and reissued. So the fix has two parts, and the second is the one people skip.

# the key sits in the web root, served on request
/var/www/html/
index.html
privkey.pem      <-- served with a 200
fullchain.pem
Delete the file, then revoke and reissue, the old key is compromised the moment it was reachable.

First, get every certificate and key file out of any directory the web server can reach, keys belong outside the document root, readable only by the process that needs them. Second, treat the leaked key as compromised: revoke the certificate with your CA and reissue against a freshly generated key. Until you reissue, anyone who grabbed the old key can still impersonate you, even after the file is gone.

Checking it from outside

Whether your private key answers an anonymous request is something a stranger settles by typing a URL, which is exactly how SurfaceCheckr checks it. It requests the handful of canonical key paths from outside, with no credentials, and flags a hit only when the response body is a real PEM private-key block, not just a 200 and not just a matching filename. It reads enough of the response to confirm the key is genuinely being served, and stops there. The same pass also covers the related catastrophes, an SSH private key in the web root and a private key sitting in your JavaScript bundle, because they all share one shape: the secret half of a key pair, served to whoever asks.

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.