Stop 24 of 42 · The Vault · Secrets in the browser

The combination printed on the brochure

The bank prints a glossy brochure for every visitor. Someone helpfully included the vault combination “so the website can use it”. Every visitor, including Mallory, gets a copy. Brochures are for public information; the combination belongs in the back office.

The VaultSources checked 25 Oct 2026

Watch it happen

Play it as

The vault combination is printed in the customer brochure. Mallory reads it and opens the vault.

Arrival

Alice and Mallory both walk into the public lobby. The bank hands every visitor a brochure (your website’s JavaScript).

1 / 5

In bank terms and app terms

In the bankIn your app
Customer brochureYour front-end JavaScript bundle and any NEXT_PUBLIC_ / VITE_ variables
Vault combinationSecret API keys, service-role keys, database passwords
Public address on the brochurePublishable keys (Stripe pk_, Firebase config, Supabase anon key with RLS on) designed to be public
Back-office tellerServer routes, API handlers or edge functions that hold the secret

Are you exposed?

You might be exposed if…
  • A secret is read from a variable starting with NEXT_PUBLIC_, VITE_ or REACT_APP_.
  • Your browser Network or Sources tab shows keys such as sk_live_, service_role, sk- (OpenAI) or an admin SDK credential.
  • The front end calls a paid third-party API (OpenAI, Twilio, SendGrid) directly with your key.
What to do about it
  1. Move every secret call into a server route, and let the browser call your route instead of the third party. Require login and add rate limits on that route so it is not an open relay for your key.
  2. Use only keys designed to be public in the browser, and pair them with rules such as Supabase RLS or Firebase security rules.
  3. If a secret ever reached the browser, rotate it immediately; deleting it from the next deploy is not enough.

Track these in your to-do list →

Ask your AI tool to fix it

Paste this into Cursor, Claude, Lovable, Bolt or whatever you build with.

Prompt
Search my front-end code and build output for secret keys exposed to the browser, including variables prefixed NEXT_PUBLIC_, VITE_ or REACT_APP_. For each real secret (service-role keys, sk_ keys, OpenAI/Twilio/SendGrid keys), move the call into a server-side API route, read the key from a server-only env var, and tell me which keys I must rotate. Leave genuinely public keys (Stripe publishable, Supabase anon) in place.

Where this comes from

The facts, figures and fixes on this page were checked against these sources on 25 Oct 2026. They are linked so you can check for yourself.

Spot a mistake or something out of date? Report a correction · How these guides are made and checked

Go deeper in isitsecure

The free, open-source scanner checks for most of the problems in these guides.