Exposed API Keys in JavaScript: How Hackers Find Your Secrets
Exposed API Keys in JavaScript: How Hackers Find Your Secrets
Here's something that keeps me up at night: I scan random sites from Product Hunt launches and Hacker News "Show HN" posts. About 1 in 5 has at least one exposed API key sitting in their JavaScript bundle. Just... out there. For anyone to grab.
And attackers do grab them. There are bots constantly crawling the web, running regex patterns against every JavaScript file they can find. The moment they hit a valid AWS key or Stripe secret, it gets exploited within minutes. Not hours. Minutes.
What Actually Gets Exposed
Your JavaScript bundle is public. Anyone can view it. When you accidentally include secrets, here's what they find:
The expensive ones:- AWS access keys (AKIA followed by 16 characters) - These get used for crypto mining. People wake up to $45,000 AWS bills.
- Stripe secret keys (sk_live_) - Full access to your payment system. Refunds, customer data, everything.
- OpenAI keys (sk-) - Get sold on Telegram. Someone runs a wrapper service on your dime.
- Firebase configs with write access - Your entire database, open to the world
- GitHub tokens - Access to your private repos
- Database connection strings - Direct access to your data
- Google Maps API keys without restrictions - Get used for other people's apps, you get the bill
- Twilio credentials - Someone sends 10,000 SMS messages
- Slack webhooks - Random messages in your channels
How They Find Them
It's not sophisticated. The tooling is trivially available.
Pattern matching. Simple regex against your JavaScript:\\\
AKIA[0-9A-Z]{16} # AWS
sk_live_[a-zA-Z0-9]{24} # Stripe
sk-[a-zA-Z0-9]{48} # OpenAI
ghp_[a-zA-Z0-9]{36} # GitHub
\\\
Real Damage I've Seen
A friend shipped an AWS key in a React app. Within 4 hours, someone had spun up EC2 instances for crypto mining. The bill was $12,000 before AWS fraud detection caught it.
Another indie hacker had their Stripe test key in production code. Except it wasn't a test key - it was live. Attacker issued refunds to themselves through a compromised customer account.
OpenAI keys are particularly popular right now. There are entire Discord servers trading them. Your key gets shared, a hundred people start making GPT-4 calls, and suddenly you've got a $2,000 bill.
How to Check Your Site
The manual way:Our Secret Scanner does all of this automatically. It downloads your JavaScript, runs pattern matching for 212+ secret types, checks for exposed source maps, and flags anything suspicious.
How to Fix It
Never hardcode secrets. Use environment variables:\\\javascript
// NO. Just no.
const stripe = require('stripe')('sk_live_abc123');
// Yes.
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
\\\
\\\
Browser → Your API → Stripe
(key lives here, never sent to browser)
\\\
\\\javascript
devtool: process.env.NODE_ENV === 'production' ? false : 'source-map'
\\\
If You've Already Leaked a Key
Don't just generate a new one. The old one is still out there and still valid.
And then figure out how it happened and fix your build process so it doesn't happen again.
Scan your site for exposed secrets Run a security audit