How to Fix Hardcoded Secrets in Cursor AI Generated Code
OverMCP Team
Quick answer
Hardcoded secrets in Cursor AI generated code—like API keys, database credentials, and JWT tokens—are a common security risk because AI models often output example values directly into source files. To fix them, immediately move all secrets to environment variables or a secrets manager, then scan your entire repository with a dedicated tool like OverMCP's secret leak scanner to catch any you missed. Never commit secrets to Git; use .gitignore and pre-commit hooks to block them automatically.
What to check first
Before writing a single line of fix code, audit your project for all possible hardcoded secrets. Here is a concrete checklist:
auth.js, middleware.js, or lib/auth.js.service_role, Firebase admin SDK keys.http://user:pass@internal-api.com.Search your entire project for patterns like sk-, AKIA, eyJ (base64 JWT), password=, secret=, api_key=, key=. Use grep -r or the built-in Cursor search with regex: (sk-[A-Za-z0-9]{20,}|AKIA[0-9A-Z]{16}|eyJ[A-Za-z0-9_-]{10,}). Run a free AI app security scanner to get a quick inventory of all exposed secrets.
Step-by-step fix
Follow this exact workflow to fix hardcoded secrets in your Cursor AI generated code. We'll use a Next.js app with Supabase as an example, but the pattern applies to any framework.
1. Identify all hardcoded secrets
Open your project and list every file containing secrets. Common culprits:
lib/supabaseClient.jspages/api/auth.jsutils/constants.js.env.local (if accidentally committed)next.config.js2. Move secrets to environment variables
Create a .env.local file (ensure it's in .gitignore already) and define variables:
# .env.local
NEXT_PUBLIC_SUPABASE_URL=https://yourproject.supabase.co
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
JWT_SECRET=my-custom-jwt-secret-that-is-long-and-randomThen reference them in your code:
// lib/supabaseClient.js (before fix - hardcoded)
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = 'https://yourproject.supabase.co'
const supabaseKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
export const supabase = createClient(supabaseUrl, supabaseKey)// lib/supabaseClient.js (after fix - env vars)
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!
const supabaseKey = process.env.SUPABASE_SERVICE_ROLE_KEY!
export const supabase = createClient(supabaseUrl, supabaseKey)For the JWT secret, update your authentication middleware:
// pages/api/auth.js (before - hardcoded)
const JWT_SECRET = 'supersecretkey123'
// After - from environment
const JWT_SECRET = process.env.JWT_SECRET3. Remove all hardcoded values from source
Search for every occurrence you identified and replace with process.env.VARIABLE_NAME. For public keys (like NEXT_PUBLIC_*), use the NEXT_PUBLIC_ prefix so they're available client-side.
4. Scan for remaining secrets
After the manual fix, run an automated scan to catch anything you missed. Use OverMCP's secret leak scanner – it checks your entire Git history, staged files, and even common misconfigurations. If you're on Vercel, you can connect your project for continuous monitoring.
5. Add pre-commit hooks to prevent future leaks
Install husky and lint-staged, then use a tool like secretlint or talisman:
npx husky add .husky/pre-commit "npx secretlint --secretlintignore .gitignore **/*"Or use a simpler regex check in .husky/pre-commit:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
# Block files containing patterns like API keys
if git diff --cached --name-only | xargs grep -l 'sk-[A-Za-z0-9]{20,}\|AKIA[0-9A-Z]{16}'; then
echo "ERROR: Found potential secret in staged files. Commit aborted."
exit 1
fi6. Rotate any leaked credentials
If you ever committed a secret, assume it's compromised. Go to the respective service (OpenAI, Supabase, AWS, etc.) and rotate the key immediately. For Supabase, go to Settings > API > Rotate service role key.
Common mistakes
Cursor AI generated apps often make these specific errors:
utils/example.js with dummy secrets that you forget to replace..env file is generated but not added to .gitignore, so it gets committed. Always check .gitignore includes .env, .env.local, .env.*.local..env.example to .env and fill in real keys, then accidentally commit the example file with real data.NEXT_PUBLIC_ for keys that should be server-only (like SUPABASE_SERVICE_ROLE_KEY). This exposes the secret in the browser.next.config.js, firebase.config.js, or aws.config.js often contain static secrets generated by Cursor.git filter-branch or BFG Repo-Cleaner to purge it. After cleanup, rotate the key anyway.Why Cursor loves hardcoding secrets
Cursor's AI model is trained on public code, which often includes example API keys like sk-test-xxx or placeholder secrets. When you prompt it to generate a Supabase client or OpenAI wrapper, it naturally outputs inline values because that's the training pattern. The AI doesn't understand your deployment environment or security best practices — it just completes the code you asked for. That's why you must treat every Cursor-generated file as a security risk until verified.
Continuous prevention
Don't rely on a one-time fix. Set up continuous security monitoring to scan every new commit and deployment. This catches secrets that slip through code review, especially in fast-moving projects. Also, educate your team (or future you) to always ask Cursor to refactor secrets into environment variables as part of the prompt: "Generate this function using environment variables for all secrets."
FAQ
What is a hardcoded secret?
A hardcoded secret is any sensitive credential (API key, password, token, or certificate) written directly into source code instead of stored securely in environment variables or a secrets manager. This makes it visible in Git history and easy to steal.
Can I use Cursor to fix hardcoded secrets automatically?
You can prompt Cursor to refactor hardcoded values to environment variables, but always verify the output manually. Cursor might miss some occurrences or introduce new secrets. Pair it with an automated scanner for thorough results.
How do I check if my Cursor project has hardcoded secrets?
Use a regex search across your codebase for common key patterns (e.g., sk-, AKIA, eyJ), or run a dedicated scanner like OverMCP's secret leak scanner which detects over 100+ secret types and checks Git history.