How scrapers find your exposed API key within hours of launch
Put a Stripe or OpenAI key in your frontend and it isn't hidden — it's published. How automated scrapers find bundled keys within hours, why 'it's only the frontend' is a myth, and how to move the key server-side.
"It's only the frontend" might be the most expensive four words in web development. A secret key in your browser code is not hidden, obfuscated or protected. It is published — as surely as if you'd put it on a billboard — and there are bots whose entire job is to read that billboard.
How the key gets there
You want your app to call a paid API — OpenAI, Stripe, a maps provider, an email service. The quick way, and the way AI builders reach for by default, is to call it directly from the browser. That means the key has to be in the JavaScript the browser downloads. It's now in your bundle, readable by anyone who opens developer tools — or any program that fetches your page.
Why it's found so fast
New deployments are not obscure. Bots continuously crawl fresh sites and public code, download the JavaScript bundles, and run pattern-matching for the tell-tale shapes of secrets:
sk-... (OpenAI)
sk_live_... (Stripe secret key)
AKIA... (AWS access key)
These patterns are unmistakable, so the search is trivial and automated. A key exposed at launch is routinely found and abused within hours, not weeks. The first sign is usually a bill — your API credit drained on someone else's traffic, or fraudulent charges run through your payment account.
You cannot "hide" a frontend key
This is the part people resist. Minifying, obfuscating, base64-ing, splitting the string across variables — none of it works. The browser has to reassemble the real key to use it, which means anyone watching the browser can too. If the client can read it, the client can leak it. There is no clever encoding that changes that.
The actual fix: move the call to the server
The key belongs somewhere the public can't reach — your server:
- Your frontend calls your own backend endpoint (no secret needed).
- Your backend holds the API key in a server-side environment variable and makes the call to the paid provider.
- The key never leaves the server and never appears in a bundle.
The one honest exception: keys that are designed to be public. Stripe's publishable key (pk_...) is safe in the frontend; its secret key (sk_...) is not. Supabase's anon key is meant to be public — but only if Row Level Security is switched on. Know which of your keys is which.
And if a secret key has already been in your frontend: treat it as compromised. Rotate it — create a new one and revoke the old — before you do anything else.
Where this fits
Keys in the bundle are item #1 on my security checklist for AI-built sites, right next to the exposed .env file that leaks them a different way. Both come down to the same root cause: a secret ended up somewhere the public can reach.
The browser is not a vault. Anything you send it, you've handed to everyone. Check whether your site is leaking a key — it takes half a minute, and it's a lot cheaper than the invoice.
See what your site exposes
Run a free audit and get concrete issues in half a minute — no signup.
Check my websiteKeep reading
The complete security checklist for AI-built sites (Lovable, Bolt, v0, Cursor)
An AI can ship a working app in an afternoon — and leave a dozen doors unlocked. This is the full checklist I run against AI-built sites, in the order the findings actually bite.
July 19, 2026
One website audit or a dozen browser tabs? All-in-one vs single-purpose scanners
There's a great free tool for each of security headers, SSL, DNS, speed, SEO and cookies. Running all of them, reconciling the results, and knowing what actually matters is the real work. The case for a single scan.
July 19, 2026