Is Your Stripe Secret Key in Your JavaScript Bundle? Here's How to Check
If you used Cursor, Claude, or ChatGPT to add Stripe payments to your app, there's a good chance your sk_live_ key is sitting in your compiled JavaScript right now. Here's how to check in 30 seconds — and fix it before someone finds it.
On this page▾
1The Problem: AI Puts Your Secret Key in Client Code
Here's what typically happens. You prompt your AI coding tool:
"Add Stripe checkout to my Next.js app"
The AI generates something like this in a React component:
// ❌ WRONG — this is a CLIENT component
"use client";
import Stripe from "stripe";
const stripe = new Stripe("sk_live_abc123...");
export function CheckoutButton() {
const handleClick = async () => {
const session = await stripe.checkout.sessions.create({
// ...
});
};
return <button onClick={handleClick}>Pay</button>;
}That sk_live_ key is now public
When Next.js compiles this component, the Stripe secret key gets baked into the JavaScript bundle. Every visitor downloads it. Anyone can open DevTools → Sources and search for "sk_live_" to find it.
2What Someone Can Do With Your Stripe Secret Key
- Create charges against any customer in your account
- Read all customer data — emails, addresses, payment methods
- Issue refunds on any transaction
- Create and manage subscriptions
- Access your entire transaction history
This is not a theoretical risk. We've found live sk_live_ keys in 11 out of 100 AI-built apps we scanned.
3How to Check in 30 Seconds
Method 1 — Free Security Scanner (easiest):
- Go to aiexposuretool.com/security
- Enter your site URL
- The scanner downloads your JS bundles and scans for
sk_live_andsk_test_patterns - Get results in 30 seconds — no signup needed
Free Stripe key scan
Scans for 17 API key types including Stripe, OpenAI, AWS, and Supabase. Passive, read-only.
Method 2 — Manual check (DevTools):
- Open your site in Chrome
- Open DevTools (F12 or Cmd+Option+I)
- Go to Sources tab
- Press Cmd+Shift+F (search across all files)
- Search for
sk_live_orsk_test_ - If you see a match — your key is exposed
4The Fix: Move Stripe to Server-Side
// ✅ CORRECT — Server-side API route
// /app/api/checkout/route.ts
import Stripe from "stripe";
import { NextResponse } from "next/server";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
export async function POST(req: Request) {
const session = await stripe.checkout.sessions.create({
mode: "payment",
line_items: [{ price: "price_xxx", quantity: 1 }],
success_url: "https://yoursite.com/success",
cancel_url: "https://yoursite.com/cancel",
});
return NextResponse.json({ url: session.url });
}// ✅ Client component — calls the API route
"use client";
export function CheckoutButton() {
const handleClick = async () => {
const res = await fetch("/api/checkout", { method: "POST" });
const { url } = await res.json();
window.location.href = url;
};
return <button onClick={handleClick}>Pay</button>;
}The secret key stays in .env.local (server only). The client component only calls the API route — no key exposed.
5Publishable Key vs Secret Key — Quick Reference
| Publishable (pk_) | Secret (sk_) | |
|---|---|---|
| OK in client JS? | ✅ Yes | ❌ NEVER |
| Can create charges? | No | Yes |
| Can read customer data? | No | Yes |
| Can issue refunds? | No | Yes |
| Starts with | pk_live_ or pk_test_ | sk_live_ or sk_test_ |
| Where to use | Browser, React, Stripe.js | Server only (API routes) |
See the bigger picture
34% of 100 AI-built SaaS apps had exposed keys. Read the case study to see how widespread this is.
Frequently Asked Questions
What's the difference between Stripe publishable and secret keys?
Publishable keys (pk_live_ or pk_test_) are meant for client-side code — they can only create tokens, not charges. Secret keys (sk_live_ or sk_test_) have full API access: create charges, refund payments, read customer data, manage subscriptions. Secret keys must NEVER be in client-side JavaScript.
How do I check if my Stripe key is exposed?
Use AI Exposure Tool's free security scanner at aiexposuretool.com/security. It downloads your JavaScript bundles and scans for sk_live_ and sk_test_ patterns. Takes 30 seconds, completely passive.
My Stripe key is exposed — what do I do?
1) Go to Stripe Dashboard → API Keys → Roll key immediately. 2) Move the key to .env.local. 3) Create a server-side API route (/api/checkout) that uses the key. 4) Never import Stripe with a secret key in a client component. 5) Re-scan to verify the fix.
Can someone actually find my key from a JavaScript bundle?
Yes. Open any website → DevTools → Sources tab → search for 'sk_live_' or 'sk_test_'. If the key is in a client component, it's in the compiled bundle. Minification doesn't hide it — the full key string is still there.
What can someone do with my Stripe secret key?
Create charges against any customer in your account, read all customer data (emails, addresses, payment methods), issue refunds on any transaction, create and manage subscriptions, and access your entire transaction history. This is not theoretical — we've found live sk_live_ keys in 11 of 100 AI-built apps we scanned.