All guides
Critical severityExposed Secrets

API keys exposed in client-side JavaScript

Anything shipped to the browser — inline scripts, bundled JS, source maps — can be read by anyone. Secret keys (OpenAI, Stripe secret, AWS, database URLs) embedded in frontend code are effectively published.

What it is

Build tools inline environment variables at compile time. If you reference a secret in client code, it ends up in the JavaScript bundle that every visitor downloads.

There's a crucial split: publishable/anon keys (Stripe pk_live, Firebase web config) are designed to be public, but secret keys (sk_live, service-role keys, provider API keys) are not and must never reach the browser.

Why it matters

A leaked provider key lets anyone run up usage on your account — LLM bills, SMS charges, cloud spend — or access data the key authorizes.

Attackers scrape JavaScript bundles at scale looking for key patterns. A committed secret is usually abused within minutes of going live.

How to fix it

Keep secrets on the server

Call third-party APIs from a server route or backend, never from the browser. The browser talks to your endpoint; your endpoint holds the key.

// app/api/summarize/route.ts (server-only)
export async function POST(req: Request) {
  const { text } = await req.json();
  const r = await fetch("https://api.openai.com/v1/responses", {
    method: "POST",
    headers: { Authorization: `Bearer ${process.env.OPENAI_API_KEY}` },
    body: JSON.stringify({ model: "gpt-4o-mini", input: text }),
  });
  return Response.json(await r.json());
}
Use the NEXT_PUBLIC_ prefix deliberately

In Next.js only variables prefixed with NEXT_PUBLIC_ are exposed to the browser. Never put a secret behind that prefix — use it only for values that are safe to be public.

Rotate leaked keys

If a secret has shipped to the browser, revoke and reissue it. Removing it from the next build doesn't invalidate copies already scraped.

FAQ

Is my Stripe publishable key (pk_live) a problem in the frontend?

No — publishable keys are meant to be public. The risk is the secret key (sk_live), which must stay server-side.

Can I just obfuscate the key?

No. Obfuscation is trivially reversible. The only fix is to keep the secret off the client entirely.

Is your app affected?

AppSafe checks for this and dozens of other issues in one free scan.

Scan my app free
API Keys in Frontend JavaScript — Why It's a Risk & How to Fix