CriticalSecurityAuto-fixable

Secret API Key Exposed in Client Bundle

A sensitive credential (Stripe secret, OpenAI API key, Supabase service role key) is prefixed with NEXT_PUBLIC_, causing it to be inlined into the browser JavaScript bundle where anyone can read it.

Typical error

NEXT_PUBLIC_ prefix used for private key

What this is

In Next.js, environment variables prefixed with NEXT_PUBLIC_ are inlined into the client bundle at build time. Any visitor can open devtools, open Sources, and read them.

Legitimate uses: analytics keys intended to be public, feature flags, public API URLs.

Catastrophic misuses FinishKit catches:

  • NEXT_PUBLIC_STRIPE_SECRET_KEY
  • NEXT_PUBLIC_OPENAI_API_KEY
  • NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY
  • NEXT_PUBLIC_SENDGRID_API_KEY

Any of the above lets an attacker bill your account, send emails from you, or read all your database rows bypassing RLS.

Why AI tools ship this

When the generated code needs a credential, the prompt-to-app builder often reaches for the most accessible env var pattern. NEXT_PUBLIC_ appears in examples everywhere, so the tool defaults to it. The generated app runs, the secret works, nobody checks the bundle output.

How to detect

Search the built output for known secret patterns:

grep -r "sk_live_" .next/static
grep -r "sk_test_" .next/static
grep -r "service_role" .next/static
grep -rE "AKIA[0-9A-Z]{16}" .next/static

Any hit means the secret is shipped to every visitor.

How to fix

  1. Rotate the secret immediately at the provider (Stripe, OpenAI, Supabase dashboard).
  2. Move the value to a non-public env var: rename NEXT_PUBLIC_STRIPE_SECRET_KEY to STRIPE_SECRET_KEY.
  3. Move any code that reads the secret into a server component, a route handler, or a server action. Never read it from a 'use client' component.
  4. Add a pre-commit scanner like gitleaks or trufflehog to prevent a recurrence.

Commonly affected tools

Glossary

Is your app affected?

FinishKit checks for this finding and 50+ more across 8 dimensions of production readiness. Free during beta.

Scan your app