For most of the web's history, there was a hard wall between the code that ran on your server and the code you handed to a visitor's browser. Secrets lived on one side of that wall. You had to go out of your way to move one across it.
That wall is gone. Not because anyone tore it down on purpose, but because the tools got so good at blurring it. A framework inlines an environment variable into the bundle at build time. A component marked for the server quietly ships its props to the client to hydrate. A desktop-style app compiles straight into the browser and brings its whole configuration along for the ride. None of that looks like a mistake while you're making it. The build succeeds. The page loads. The key is just... there, in the source, for anyone who opens the tab.
What we kept seeing
We watched it happen across every modern stack. A NEXT_PUBLIC_ variable that was meant for a public analytics id, holding a private one. A Blazor WebAssembly app shipping its assemblies, and the config baked into them, to the browser to run. An ASP.NET setting that belonged in a secret store, serialized into the page instead. A Supabase service_role key, the one that skips every access rule you wrote, sitting in a script tag.
And here is the part that made us build this instead of just tutting about it: it was not happening to careless people. Nobody is the problem here. The people shipping these leaks were building real products that real users wanted. Some were on their first app. Plenty were seasoned engineers who had shipped safely for a decade. The convenience that makes it possible to build a working product in an afternoon, the AI assist, the framework that handles the boring parts, is the same convenience that quietly carries a secret across a boundary you can no longer see. The tool that saved you an hour also moved the wall, and it did not tell you.
So we built the thing that reads the boundary
SurfaceCheckr looks at your site the way a stranger on the internet does: from outside, with no login, no agent, and no permission needed, because everything it reads is already being served to the public. It reads your headers, your certificate, your DNS, the files sitting in your web root, and the JavaScript your pages hand to every visitor. Then it tells you, in one grade, what stands out, and behind that, exactly which line to change.
It is passive, and it stays passive. It never sends an attack payload, never tries a login, never POSTs, never writes. That is a deliberate constraint, not a limitation we are apologizing for: it means you can point it at a production site you care about without a second thought, and it means what it finds is what an attacker can already see, today, without doing anything clever.
The discipline behind it
A security tool that cries wolf is worse than no tool at all, because you learn to ignore it. So we hold every one of our 500+ passive checks to the same bar: a finding fires only when the evidence is unambiguous. A false positive is a bug we go and fix at the gate, not an edge case we ask you to excuse. When we tell you something is wrong, we have the exact request and response that proves it, and we are not guessing about a version window or a key format, we check it against the primary source first.
The grade is free, for any domain, always. If you want the specifics, the file, the key, the exact path, and the fix, that is the part you pay for. We think that is the honest shape for a tool like this: show anyone how exposed they are for nothing, and charge only for the work of closing it.
Where to go next
If you want the mechanics of how the scan works, the safety model, and how to recognise or opt out of it, that is all on the scanner info page. If you just want to know what your own site is handing out right now, the fastest way to find out is to try it.