Did you leave an API key in an HTML comment?
View source on any page you've shipped and scroll past the markup to the parts the browser doesn't render. The <!-- ... --> blocks. They're invisible on the page and fully readable in the source, which is exactly why they're a good hiding place for things that shouldn't be there: a stray key, a token someone pasted in to test something, a note that quotes a password. The comment doesn't show up when the page loads, so it's easy to forget it went out at all. It went out. It's in the bytes you serve to every visitor.
A comment feels private because it's written for the next developer, not the user. That's the trap. The browser treats it as decoration and skips it; a stranger reading the raw HTML treats it as text and reads it. There's no permission boundary on a comment. If it's in the document, it's public.
How a key ends up in a comment
It's almost never deliberate. Someone is debugging an integration and pastes the real key into the template to rule out a config problem, then comments it out instead of deleting it because that's the faster keystroke. The page ships. Or a server-side templating engine prints a value into a comment for debugging (<!-- rendered with config: {...} -->) and the config object happens to carry a secret. Or an old block of markup that called a third-party service gets commented out during a rewrite, and the API key in the inline <script> rides along inside the comment.
The mechanism doesn't matter to the person reading your source. What matters is what the comment contains. A commented-out sk_live_ Stripe key still charges cards. A ghp_ GitHub token in a <!-- TODO: rotate this --> still reads your private repos. A commented database password is still the password. Commenting code out changes whether the browser runs it. It does nothing to whether a stranger can read it.
This is a different finding from the low-severity stuff that also hides in comments: a <!-- TODO: /admin has no auth yet --> is intel an attacker uses to aim, but it isn't a credential. A live key in a comment is the credential itself. Same surface, much higher stakes, and the fix is more urgent: you can't just tidy it up, you have to assume it's already been read.
Strip comments in the build, then rotate
Two things have to happen, in this order. Rotate first, because the key has been public for as long as the page has been live and you have no log of who read it. Then stop it recurring by making your production build strip comments out of the served HTML.
<!-- debug: live key for the checkout test sk_live_51HxQp…Yz --> <div id="checkout"></div>
Most minifiers drop comments by default once you run them in production mode; the gap is usually a build that minifies JavaScript but serves the HTML template untouched. Check that your HTML goes through the same minify step. For server-rendered templates, make sure debug blocks that interpolate config are gated behind a development-only flag so they can't render in production at all. And treat any secret that has been in a shipped comment as burned: revoke it and issue a new one, the same as you would for a key found anywhere else in the page source.
The thing about a comment is that it reads as private to the person who wrote it and as plain text to everyone else, and the only way to know which secrets slipped into yours is to read the source the way a stranger does. That's the read SurfaceCheckr makes. It pulls the HTML you serve, runs the same secret-pattern engine over the comment blocks that it runs over your scripts, and flags a comment only when it carries a genuine key, not a placeholder or a public token. It reads the comment and stops there; it never uses what it finds. Two minutes tells you whether there's a working credential sitting in a part of the page you stopped looking at.
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.