Exposed API Keys: What They Are and Why They're Dangerous

Share

TL;DR

An exposed API key is like leaving your house key under the doormat with a sign pointing to it. If your Stripe, OpenAI, or AWS keys are visible in your frontend code or GitHub repo, anyone can use your services and rack up charges on your account. Fix this by rotating keys immediately and moving them to server-side environment variables.

API keys are the passwords that let your app talk to other services. Stripe uses them for payments. OpenAI uses them for AI requests. AWS uses them for cloud services. These keys are meant to be secret. When they're exposed, bad things happen.

In vibe-coded apps, exposed API keys are the single most common security issue. The AI generates code that works, but it often puts keys directly in frontend JavaScript where anyone can see them.

What Is an Exposed API Key?

An exposed API key is a secret credential that has been accidentally made visible to the public. This happens in several ways:

  • Hardcoded in frontend JavaScript: The key is written directly in your React, Vue, or vanilla JS code that gets sent to browsers.
  • Committed to a public GitHub repository: Even if you delete it later, the key is still visible in git history.
  • Stored in publicly accessible files: Your .env file is accessible at yourdomain.com/.env.
  • Visible in network requests: The key is sent in API calls that can be seen in browser developer tools.

If someone can see your key, they can use it. Most services can't tell the difference between a request from your app and a request from an attacker using your stolen key.

Real Example: A founder shipped a vibe-coded app with their OpenAI API key in the frontend. Within 48 hours, someone found it and made thousands of API calls. The resulting bill was over $2,000 before they noticed.

What Can Happen If My Keys Are Exposed?

The consequences depend on which service the key belongs to:

ServiceExposed Key RiskPotential Impact
OpenAIUnlimited API usage$1,000s in unexpected charges
Stripe (Secret Key)Access to payment data, refundsCustomer data exposure, fraud
AWSFull cloud access$10,000+ crypto mining bills
FirebaseDatabase read/writeData theft, deletion
SupabaseService role accessComplete database exposure
TwilioSMS sending capabilitySpam campaigns, charges
SendGrid/ResendEmail sending capabilityPhishing campaigns, reputation

Common AWS Impact: $10,000+ bills when exposed credentials are used for cryptocurrency mining. Attackers spin up expensive GPU instances within hours of finding keys.

How Do I Check If My Keys Are Exposed?

Here's how to check manually:

  1. Open your website in Chrome or Firefox
  2. Press F12 to open Developer Tools
  3. Go to the Sources tab and search for your API key value
  4. Go to the Network tab and look at request headers and bodies
  5. Check your GitHub repo for any committed secrets

If you can find your keys using these methods, so can an attacker.

What Exposed Keys Look Like in Code

Here's an example of exposed keys in vibe-coded React code:

// BAD: Key is visible to anyone who views your JavaScript
const openai = new OpenAI({
  apiKey: "sk-proj-abc123xyz789..."
});

// BAD: Key in frontend environment variable (still visible)
const stripe = new Stripe(process.env.NEXT_PUBLIC_STRIPE_SECRET_KEY);

The problem is that anything in frontend JavaScript gets sent to the browser. Users can view the source code, search through bundled files, and find these values.

How Do I Fix Exposed API Keys?

If your keys are currently exposed, follow these steps in order:

Step 1: Rotate Your Keys Immediately

Go to each service's dashboard and generate new keys. Don't just hide the old ones. Replace them. Here's where to do this:

  • OpenAI: platform.openai.com → API Keys → Create new key
  • Stripe: dashboard.stripe.com → Developers → API Keys → Roll keys
  • Supabase: app.supabase.com → Project Settings → API → Generate new key
  • AWS: AWS Console → IAM → Users → Security credentials → Create access key

After generating new keys, revoke the old ones. This invalidates any stolen copies.

Step 2: Move Keys to Server-Side Code

API keys should never be in code that runs in the browser. Here's the correct approach:

// GOOD: API route on the server (Next.js example)
// File: /pages/api/chat.js or /app/api/chat/route.js

export async function POST(request) {
  const openai = new OpenAI({
    apiKey: process.env.OPENAI_API_KEY // Server-side only
  });

  // Your API logic here
}

The key difference: NEXT_PUBLIC_ prefix means client-visible. Without that prefix, the variable only exists on the server.

Step 3: Add Keys to Your Deployment Platform

Add your keys as environment variables in your hosting platform:

  • Vercel: Project Settings → Environment Variables
  • Netlify: Site Settings → Environment Variables
  • Railway: Project → Variables
  • Render: Dashboard → Environment

Step 4: Update Your .gitignore

Make sure your .env file is never committed:

# .gitignore
.env
.env.local
.env.*.local

Which Keys Are Safe in the Frontend?

Some keys are designed to be public. Here's how to tell:

Key TypeFrontend OK?Notes
Supabase anon keyYesDesigned for frontend, but requires RLS
Firebase configYesPublic by design, needs security rules
Stripe publishable keyYespk_live_ or pk_test_ only
Google Maps API keyYesWith domain restrictions enabled
Stripe secret keyNOsk_live_ or sk_test_ are secrets
OpenAI API keyNOsk-proj_ must be server-side only
Supabase service role keyNOBypasses RLS, server-only
AWS credentialsNONever expose access keys

API Key Security Checklist

  • All secret keys stored in environment variables
  • No keys hardcoded in frontend JavaScript
  • No NEXT_PUBLIC_ prefix on secret keys
  • .env files added to .gitignore
  • Old exposed keys rotated and revoked
  • API calls to sensitive services routed through server
  • GitHub repo checked for committed secrets
  • Public keys have proper restrictions enabled

What is an exposed API key?

An exposed API key is a secret credential that has been accidentally made visible to the public. This happens when keys are included in frontend JavaScript code, committed to public GitHub repositories, or stored in files that are accessible via a web browser. Anyone who finds an exposed key can use it as if they were you.

What happens if my API key is exposed?

The consequences depend on which service the key is for. Exposed OpenAI keys can result in thousands of dollars in charges as attackers use your account for their own requests. Exposed Stripe keys might allow access to customer payment data. Exposed AWS keys have led to cryptocurrency mining bills exceeding $10,000.

How do I know if my API keys are exposed?

Open your website in a browser, press F12 to open developer tools, and search for your key values in the Network tab and Sources panel. If you can see your keys there, so can anyone else. Automated security scanners can also detect exposed keys in your deployed application.

How do I fix exposed API keys?

First, rotate your keys immediately by generating new ones in the service dashboard and revoking the old ones. Then move all keys to environment variables and ensure they are only accessed from server-side code, not frontend JavaScript. Never commit keys to version control.

Are Supabase and Firebase keys safe to expose?

The anon/public keys for Supabase and Firebase config are designed to be in frontend code, but they require proper security rules. For Supabase, enable Row Level Security (RLS). For Firebase, configure Firestore Security Rules. The service role key for Supabase should never be exposed.

Check Your Keys in Minutes

Run a free security scan to find exposed API keys and other vulnerabilities.

Start Free Scan
Vulnerability Guides

Exposed API Keys: What They Are and Why They're Dangerous