All articles

Frontend API key leak: find and fix it before launch

6 min read

Free security scan

Is your Next.js app secure? Find out in 30 seconds.

Paste your URL and get a full vulnerability report — exposed keys, missing headers, open databases. Free, non-invasive.

No code access requiredSafe to run on productionActionable report in 30

A frontend api key leak is any credential or privileged token shipped into browser-readable code. The fix is simple in principle: find the key in built assets, confirm whether it grants real access, rotate it, move sensitive calls behind a server route, and add automated scanning before every release.

Find a frontend API key leak

Start with the production build, not only the source repository. Many leaks appear after bundling, environment injection, error page generation, or static export. browser code is public, so anything in JavaScript, HTML, source maps, or client-side config can be copied by a user or bot.

Look for these common patterns first:

  • public identifier values that are safe by design, such as analytics IDs or publishable payment keys.
  • real secret values used for admin APIs, server-to-server calls, AI providers, databases, email, storage, or webhooks.
  • runtime configuration leaks from NEXT_PUBLIC_, VITE_, PUBLIC_, or similar prefixes.
  • source maps that expose original variable names, comments, or removed test code.
  • Old preview deployments that still contain credentials after the main app was fixed.

A fast manual check is to open your built output and search for patterns like sk_, AKIA, Bearer, secret, service_role, private_key, and provider-specific prefixes. Do not rely only on your editor. Scan the deployed site because the browser receives the final truth.

For a more systematic check, use a client-side secret scanner or run a JavaScript bundle scan against the actual public URL. This catches generated files, lazy-loaded chunks, and static JSON files that are easy to miss during code review.

Confirm real exposure risk

Not every visible key is equally dangerous. Some providers intentionally expose restricted browser keys. The audit question is whether an attacker can use the value outside your intended flow, from their machine, at scale, or with higher privileges than a normal visitor.

Use bundle search to locate the value, then test context carefully. Check where the key is called, which API endpoint accepts it, and what identity or permissions it carries. A key that can read invoices, send email, modify records, create AI completions, or access storage is not a frontend-safe value.

Review network requests in the browser developer tools. If the frontend calls a third-party API directly with a bearer token, that token is exposed. If the frontend calls your own backend and your backend adds the credential server-side, the browser should never receive the sensitive value.

The most common false sense of safety is domain restriction. Referrer or origin restrictions reduce abuse, but they are not a substitute for authorization. Attackers can still inspect endpoints, replay weak flows, or abuse any operation your app allows from the browser. Treat restrictions as guardrails, not as secret storage.

Check permission scope before deciding severity. A read-only map tile key with strict origin controls is usually low risk. A service role database key is critical. A payment publishable key is expected in the client, but a payment secret key is urgent. A model provider key can create direct cost exposure if it can be reused.

A realistic secure pattern is to replace direct browser calls with a small backend route. The route reads the sensitive value from server environment variables and returns only scoped, short-lived data to the client.

ts
// app/api/maps-token/route.ts
import { NextResponse } from 'next/server';

export async function GET() {
  const token = process.env.MAPS_SERVICE_TOKEN;
  if (!token) return NextResponse.json({ error: 'missing token' }, { status: 500 });

  const scoped = await createShortLivedMapsToken(token, { ttlSeconds: 300 });
  return NextResponse.json({ token: scoped });
}

This pattern keeps the provider credential off the page. It also gives you a place to add rate limits, user checks, logging, and abuse controls. If the app is AI-built or generated quickly, this server boundary is one of the highest-value fixes.

Fix and prevent recurrence

Once you find a sensitive value, rotate first. Do not wait until after refactoring if the current value is live. Rotation cuts off unknown copies from browser caches, CDN edges, screenshots, logs, extensions, and automated crawlers that may already have indexed the asset.

Then remove the cause. move secrets server-side for any operation that requires privileged access. In modern frontend frameworks, this usually means using server actions, API routes, edge functions, or a separate backend service. Only values explicitly designed for public use should be prefixed for client exposure.

Use this short remediation checklist:

  1. Revoke or rotate the exposed credential in the provider dashboard.
  2. Remove the value from client environment variables and build output.
  3. Replace direct provider calls with a server-side endpoint.
  4. Add authorization checks before the server endpoint performs work.
  5. Add rate limits and cost controls for expensive operations.
  6. Purge CDN caches and redeploy clean assets.
  7. Review access logs for suspicious use during the exposure window.
  8. Add a prelaunch secret scan to your release workflow.

Also remove secrets from git history if they were committed. Rotation still matters more than history rewriting, because old commits may already exist on developer machines, CI logs, forks, caches, or third-party integrations. History cleanup is hygiene. Credential rotation is the security boundary.

For launch reviews, run an external security scan against the deployed app, then use a deep scan when you need broader crawl coverage across routes, assets, forms, and generated pages. The important detail is to scan what users and attackers can actually reach.

Build-time conventions help prevent repeat mistakes. Mark public variables clearly, keep secret variable names out of frontend code, and block builds when risky patterns appear. deny by default is the safer rule: a variable is server-only unless someone intentionally documents why it belongs in browser code.

Ship with safer defaults

Before launch, assume generated code may have copied examples from documentation, placed provider keys in public config, or used direct browser calls for speed. That pattern works in demos but fails in production. assume compromise for any sensitive value already shipped to a public page.

The safer target is clear: browser code receives public identifiers, session-bound data, or short-lived tokens, while durable secrets stay behind server controls. If you scan built assets, verify permissions, rotate exposed values, and enforce server-side boundaries, you reduce both breach risk and surprise usage bills.

Faq

Is every visible API key a security issue?

No. Some keys are meant to be public, including certain publishable, analytics, and map keys. The issue is whether the value grants privileged access, creates billable usage, bypasses user authorization, or works outside the intended browser context. Always verify provider documentation and actual permissions.

Can domain restrictions make a browser key safe?

Domain restrictions help, but they do not make a sensitive credential secret. They can reduce casual reuse, yet attackers may still abuse allowed frontend actions or exploit weak backend assumptions. Use restrictions for public keys, not as protection for server-side credentials.

What should i do after finding an exposed key?

Rotate the key immediately, remove it from browser-readable code, redeploy, and purge cached assets. Then check logs for misuse during the exposure window. If the key touched customer data, billing, authentication, or admin functions, treat it as a security incident and document the response.

If you want a quick prelaunch check, AISHIPSAFE can scan your public app for exposed secrets, risky assets, and launch-blocking security issues.

Free security scan

Is your Next.js app secure? Find out in 30 seconds.

Paste your URL and get a full vulnerability report — exposed keys, missing headers, open databases. Free, non-invasive.

No code access requiredSafe to run on productionActionable report in 30
frontend api key leak: find and fix it before launch · AISHIPSAFE