Critical severity · Lovable

Hardcoded API key in JS on Lovable

An API key is hardcoded in your client-side JavaScript. Anyone who views your site source can extract it. The fix has three steps: (1) rotate the key immediately — assume it is compromised; (2) move the API call to your server (API route, server action, or serverless function) so the key never ships to the browser; (3) add guardrails — prefix only server secrets without NEXT_PUBLIC_, scan builds for leaked keys. Do not try to "obfuscate" the key — it will be found.

The fix for Lovable

Lovable

Prompt Lovable: 'Move all third-party API calls to server-side functions. No API keys should exist in the frontend code. Rotate any exposed keys in the provider dashboard first.'

Why it matters

Attackers run automated bundle-scanning tools against popular sites. An exposed OpenAI, Stripe, or cloud key is drained within hours of publication — sometimes minutes. Your bill can run to thousands of dollars before you notice.

Confirm the fix worked

Scan your Lovable site to confirm this finding is gone.

AI prompt

Apply across your codebase

Paste this into Cursor, Lovable, Bolt, v0, or Claude Code.

Find every API key in my client-side code. For each one: (1) tell me which service it belongs to so I can rotate it; (2) determine if the API call needs to happen in the browser (it usually does not); (3) move the call to a server-side route handler or server action that reads the key from an env var without NEXT_PUBLIC_ prefix; (4) update the frontend to call my endpoint instead. Provide the rotation URL for each service.

FAQ

Frequently asked questions

But the user needs to make the API call from their browser for latency.
Then use a signed, time-limited credential (like S3 presigned URLs, Twilio Access Tokens, or OpenAI's ephemeral keys) generated server-side per-request. Never the raw master key.
My framework variables all start with NEXT_PUBLIC_. Is that fine?
For public values yes (Stripe publishable key, Supabase anon key). For secret values no — `NEXT_PUBLIC_` inlines the value into the browser bundle. Use `NEXT_PUBLIC_` only for values that are meant to be public.