Exposed API keys in JavaScript bundles: what AI builders leak and how to fix it
Everything in your frontend bundle is public. Env vars prefixed VITE_, NEXT_PUBLIC_ or REACT_APP_ are compiled into the JavaScript every visitor downloads, and source maps can expose even more.
Safe in the browser
- Supabase anon / publishable key (protected by RLS)
- Stripe publishable key (
pk_) - Firebase web config (with API restrictions)
Never in the browser
- Supabase
service_roleorsb_secret_keys - OpenAI, Anthropic and other LLM API keys
- Stripe secret keys (
sk_live_,rk_live_) - AWS, GitHub, Slack, SendGrid, Resend tokens and private keys
Fix
Move the call into a server-side function (Supabase Edge Function, API route, Cloudflare Worker) that reads the key from a server-only secret. Then rotate the leaked key: create a new one, deploy it, and only then revoke the old one.
Check your app now
Free, read-only public check: no sign-up, no card. Headers and HTTPS only. Deep scan (leaked keys, open Supabase tables, .env/.git) after you verify you own the domain.