All vulnerabilities
CriticalA02:2021CWE-798Sensitive Data Exposure

Exposed Secrets & API Keys

Hardcoded API keys, tokens, and credentials accidentally leaked in JavaScript bundles, source maps, or public endpoints — a leading cause of cloud breaches.

What Are Exposed Secrets?

Exposed secrets occur when API keys, database passwords, tokens, or other credentials end up in places accessible to the public — JavaScript bundles, source maps, .env files committed to git, or API responses. Anyone who finds them gains the same access as your application.

AI coding tools frequently suggest patterns like const API_KEY = "sk-..." directly in frontend code, creating secrets that ship to every user's browser.

How It Happens

Hardcoded in frontend JavaScript:

// This ends up in your Next.js bundle — visible to everyone
const OPENAI_KEY = "sk-proj-abc123..."
const SUPABASE_SERVICE_KEY = "eyJhbGc..."  // service_role key — admin access!
 
const response = await fetch("https://api.openai.com/v1/...", {
  headers: { Authorization: `Bearer ${OPENAI_KEY}` }
})

Committed .env file:

# .env accidentally committed to public GitHub repo
DATABASE_URL=postgresql://admin:password123@db.example.com/prod
STRIPE_SECRET_KEY=sk_live_abc123...

Source maps exposing server code:

# .next/static/chunks/app/api/route.js.map
# Contains original source with hardcoded credentials

Real-World Impact

  • Full cloud account takeover — AWS keys let attackers spin up resources, access S3
  • Database breach — direct database URL gives read/write access to all data
  • Billing fraud — OpenAI/Stripe keys used to rack up charges
  • Supply chain attacks — npm tokens used to publish malicious packages
  • Customer data theft — Supabase service_role key bypasses all RLS policies

How to Fix

Frontend (Next.js) — only NEXT_PUBLIC_ vars go to the browser:

// ✅ Safe — public key, designed for browser use
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
 
// ❌ Never use service_role or secret keys in frontend code
// const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY  // Server only!

Backend — always use environment variables:

import os
 
OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]  # Set in .env, never hardcoded
DATABASE_URL = os.environ["DATABASE_URL"]

Git hygiene:

# .gitignore — always include these
.env
.env.local
.env.production
*.pem
secrets/

Rotate immediately if exposed — treat any leaked key as compromised.

What VibeWShield Detects

VibeWShield scans JavaScript bundles, source maps, and API responses for patterns matching OpenAI keys (sk-), Anthropic keys (sk-ant-), Google keys (AIza), AWS credentials (AKIA), Stripe keys (sk_live_), and generic password/secret/api_key patterns. It also checks for exposed .env and source map files.

#secrets#api-keys#credentials#javascript

Free security scan

Test your app for Exposed Secrets & API Keys

VibeWShield automatically checks for Exposed Secrets & API Keys and 40+ other vulnerabilities using 63 scanners — in under 3 minutes, no signup required.

Scan your app free