How to find leaked API keys in your website's JavaScript (and fix them)
A practical guide to finding secret API keys exposed in client-side JavaScript, telling public keys from secret ones, and moving API calls to the server safely.
If your website calls an AI API, a payment API or a cloud service directly from the browser, the key that authorises that call is in your JavaScript. Anyone can read it. This guide shows how to find such keys, decide which ones matter and fix the problem properly.
Why this happens so often
Front-end frameworks bundle environment variables into the browser code when they are prefixed for public use, for example NEXT_PUBLIC_, VITE_ or REACT_APP_. AI coding tools often reach for these prefixes because they make the code work immediately. The result works, and it also publishes the key.
Public keys vs secret keys
Not every key in JavaScript is a leak. Some are designed to be public:
| Key | Safe in the browser? |
|---|---|
Stripe publishable key (pk_live_…) |
Yes |
Stripe secret key (sk_live_…) or restricted key (rk_live_…) |
No |
Supabase anon key, with Row Level Security enabled |
Yes |
Supabase service_role key |
No, it bypasses Row Level Security |
| Google Maps or Firebase browser key, restricted by referrer | Yes, if restricted |
OpenAI (sk-…) or Anthropic (sk-ant-…) keys |
No |
AWS access key ID (AKIA…) with its secret |
No |
Rule of thumb: if the key can spend money, send email, or read or write private data without any other check, it must never reach the browser.
How to find leaked keys
Option 1: automated scan
Run a free leaked API key check. Wardzo loads your pages, collects the JavaScript files they reference and matches known key formats. Results are masked.
Option 2: manually in DevTools
- Open your site, then DevTools, then the Sources (Chrome) or Debugger (Firefox) tab.
- Use Search all files (Ctrl/Cmd + Shift + F).
- Search for prefixes:
sk-,sk_live_,rk_live_,sk-ant-,AKIA,ghp_,xoxb-,SG.andservice_role.
Also check whether your JavaScript references source maps (//# sourceMappingURL=). If those maps are public, your original source code, including any hard-coded values, can be reconstructed.
How to fix it
1. Revoke the key first
Assume a leaked key has already been copied. Revoke it in the provider's dashboard and check the usage logs.
2. Keep the new key on the server
Store it in an environment variable without a public prefix, so the bundler never includes it in browser code.
3. Call the provider from a server route
In Next.js, for example, create a route handler that reads the key from process.env and calls the API. The browser calls your route, never the provider. Add authentication and rate limiting to that route, otherwise you have only moved the problem.
4. Re-scan after deploying
Scan again to confirm the key is gone from every bundle, including old cached chunks that might still be served.
Keep it from happening again
- Add secret scanning to your repository and CI.
- Turn off production source maps unless you upload them privately to your error tracker.
- Monitor your live site weekly, because the next AI-generated change can reintroduce the problem.
Related
- Leaked API key checker
Free tool that scans the JavaScript your website serves for leaked secret API keys from OpenAI, Anthropic, Stripe, AWS, GitHub, Supabase and more. Results are masked and never stored in full.
- What are source maps, and are public source maps a risk?
Source maps are .map files that map minified JavaScript back to the original source code. Publicly served production source maps expose your full front-end source.
- Website security and SEO checks for vibe coders
Built your site with Lovable, Bolt, v0, Replit or Cursor? Wardzo checks the live result for leaked API keys, exposed files, missing security headers and SEO mistakes, and gives you fixes you can paste into your AI.