View source on a surprising number of production websites and you'll find API keys sitting in plain text. Stripe publishable keys mixed in with Stripe secret keys. AWS access key IDs paired with their secret counterparts. OpenAI API keys embedded in client-side JavaScript that anyone can copy with a right-click.
This isn't a theoretical risk. Automated scrapers continuously scan public websites and GitHub repositories for leaked secrets. When they find an AWS key, they spin up cryptocurrency mining instances within minutes. When they find a Stripe secret key, they can issue refunds or access customer payment data. A leaked OpenAI key can rack up thousands in API charges before the owner notices.
How secrets end up in frontend code
The most common path is a developer who uses environment variables locally but hardcodes values for a quick test, then forgets to remove them before deploying. The second most common is a build process that injects server-side environment variables into client-side bundles without filtering. The third is copy-pasting configuration snippets from documentation without understanding which values are safe to expose publicly and which are not.
Some keys are designed to be public. Stripe publishable keys, Google Maps client-side API keys with proper referrer restrictions, and reCAPTCHA site keys are all meant to appear in frontend code. The danger is when server-side secrets get mixed in with these public keys.
The pattern list
The API Secret Leakage Audit scans your page's HTML and linked JavaScript files for over 20 known secret patterns:
- Cloud providers: AWS access key IDs (
AKIA...), Azure connection strings, GCP service account JSON - Payment processors: Stripe secret keys (
sk_live_...), PayPal client secrets - Communication platforms: Twilio auth tokens, SendGrid API keys, Mailgun private keys
- AI services: OpenAI API keys (
sk-...), Anthropic API keys - Developer tools: GitHub personal access tokens (
ghp_...), GitLab tokens, Slack webhook URLs, Slack bot tokens - Authentication: JWTs in page source, private RSA/EC keys, base64-encoded credentials
- Databases: MongoDB connection strings with credentials, PostgreSQL connection URIs with passwords
Each pattern uses the actual format of the secret (prefix patterns, character sets, lengths) to minimize false positives. A random string that happens to start with sk_ won't trigger a flag unless it matches the full Stripe secret key format.
What to do when you find a leak
If the audit finds a real secret in your frontend code:
-
Rotate the key immediately. Don't just remove it from the code. The moment a secret appears in page source, assume it's been scraped. Generate a new key in the provider's dashboard and update your server-side configuration.
-
Check your provider's audit logs. Most cloud and API providers log every request made with each key. Look for unauthorized usage between when the key was deployed and when you rotated it.
-
Move the secret server-side. If the key is needed for an API call, that call should happen on your server, not in the browser. Use a serverless function or API route as a proxy between your frontend and the third-party API.
-
Add secrets scanning to your deploy process. Tools like git-secrets, truffleHog, or your CI provider's built-in secret scanning can catch leaked keys before they reach production.
The one thing you should not do is assume nobody noticed. Automated scanners index public web pages continuously. If the key was live for even a few hours, treat it as compromised.
If you're building API integrations for the first time and want to avoid these mistakes from the start, The $97 Launch covers the proxy pattern for safely calling third-party APIs from static sites.
Fact-check notes and sources
- GitGuardian's 2024 State of Secrets Sprawl report found 12.8 million new secret occurrences in public GitHub commits in 2023. Source: GitGuardian, "State of Secrets Sprawl 2024"
- AWS automated abuse of leaked keys: AWS documents that compromised access keys are routinely used for cryptocurrency mining within minutes of exposure. Source: AWS Security Blog
- Stripe key format documentation: Stripe Docs, "API keys"
Related reading
- CSP strictness audit — Content Security Policy catches some exfiltration
- Security headers overview — defense in depth for your site
- Serverless posture audit — securing the functions that should hold your secrets
- Universal file exposure audit — other files that shouldn't be public
This post is informational, not security-consulting or legal advice. Mentions of AWS, Stripe, OpenAI, and other third parties are nominative fair use. No affiliation is implied.