← Blog/Case Study

A Founder Lost $2,500 Because His AI-Coded App Shipped a Stripe Secret Key in the Frontend

The app worked. Payments processed. Customers signed up. Then someone opened DevTools.

May 21, 2026·Talon Research

$87,500

Fraudulent charges

175

Customers hit

$2,500

Non-refundable loss

What happened

In February 2026, a startup founder named Anton Karbanovich built a paid web application using Claude Code. The app worked. It accepted payments through Stripe. Customers signed up and started paying. By every visible metric, the launch was successful.

The problem was invisible. Claude Code had placed the Stripe secret API key directly in the frontend JavaScript bundle. Not the publishable key, which is designed to be public. The secret key. The one that can create charges, issue refunds, pull customer payment details, and modify account settings. It was sitting in the browser, readable by anyone who pressed F12.

Attackers found it. They charged 175 of his customers $500 each, totalling $87,500 in fraudulent transactions. Stripe reversed the charges, but kept its processing fees. Karbanovich absorbed $2,500 in non-refundable losses. He posted the story publicly on LinkedIn and said: “I still don’t blame Claude Code. I trusted it too much.”

Why AI tools do this

AI coding tools optimise for working code. When you tell them to add Stripe payments, they will produce a component that processes charges successfully. Whether the key is in the frontend or the backend is an implementation detail that the model resolves based on whatever gets to “working” fastest.

For Stripe specifically, the fastest path is often importing the Stripe SDK directly in a React component and passing the secret key inline. The code works. The charges go through. The tests pass. There is no error message, no warning, no red flag in the terminal. The only signal that something is wrong is knowing that a Stripe secret key should never leave your server.

This is not a bug in the AI tool. It is a gap in the feedback loop. The model does not know which keys are sensitive and which are not. It does not reason about what an attacker could do with a given credential. It produces code that satisfies the stated requirement, and “process payments” does not include “keep the secret key on the server.”

How fast exposed keys get found

The window between exposure and exploitation is measured in minutes, not days. Automated credential harvesters run continuously against public JavaScript bundles, GitHub repositories, and package registries. These are not sophisticated operations. They are simple scripts that scan for known key patterns and test them against the issuing service’s API.

A Stripe secret key starts with sk_live_. An AWS secret key has a recognisable format. A Supabase service role key starts with eyJhbGci. These patterns are trivial to match with a regex. The bots that harvest them are not breaking into anything. They are reading code that was published to the open internet.

In our own scanning of over 12,000 recently launched apps, we found credentials exposed in public GitHub repositories tied to 87 different domains. Connection strings, private keys, API tokens, and database passwords. Each one of those was exploitable the moment it was committed.

Stripe is not the only key that matters

The Stripe story made headlines because there was a clear dollar figure attached. But the same exposure pattern applies to every secret an app depends on.

Exposed keyWhat an attacker can do
Stripe secret key (sk_live_)Create charges, issue refunds, access customer payment data
Supabase service role keyBypass all row-level security, read/write/delete any table
AWS secret access keySpin up infrastructure, access S3 buckets, run up a billing tab
Firebase admin credentialRead/write any Firestore document, access user auth records
Database connection stringDirect access to production data, no application layer in between
OpenAI / Anthropic API keyRun up usage charges against your account
GitHub personal access tokenAccess private repositories, push code, create releases

The common thread is that every one of these keys grants access that should never leave the server. And every one of them can end up in frontend code or a public repository when an AI tool takes the shortest path to “working.”

How to check if you are exposed

This takes five minutes.

01

Check your frontend bundles

Open your app in a browser. Open DevTools (F12). Go to Sources. Search the JavaScript files for sk_live_, sk_test_, supabase, eyJhbGci, AKIA, AIza, mongodb+srv, and postgres://. If any of those appear, you have a key in your frontend that should not be there.

02

Check your GitHub repositories

If your repos are public, run TruffleHog or GitLeaks against them. These tools scan your entire git history, not just the current files. A secret committed six months ago and deleted in the next commit is still in the history and still exploitable.

03

Check your environment files

Request /.env from your production domain. If you get anything back other than a 403 or 404, your environment file is publicly accessible and every secret in it is compromised.

04

Run a scan

Talon checks all of the above automatically. Free surface scan, no account required, results in about a minute.

How to fix it

If you find a secret in your frontend or a public repo, the fix has two parts and the order matters.

First, rotate the key. Do not just move it to the backend. The old key is already compromised. Go to the service’s dashboard (Stripe, Supabase, AWS, wherever) and generate a new key. Revoke the old one. This is the only step that stops active exploitation.

Second, move the operation to the server. Any code that uses a secret key needs to run in a server-side route, API endpoint, or serverless function. The frontend calls your backend, your backend calls the service. The secret key never leaves the server.

For Stripe specifically, this means creating a server-side API route (like /api/checkout) that creates the Checkout Session using the secret key, and having the frontend redirect to the Stripe-hosted checkout page using the session URL. The publishable key (pk_live_) is fine in the frontend. The secret key (sk_live_) is not. Ever.

The takeaway

AI coding tools are not going to check whether the code they produce is safe to deploy. That is your job. The tools are fast, capable, and completely indifferent to whether a secret key ends up in the browser or on the server.

Karbanovich’s story is a $2,500 lesson. It could have been much worse. If the attackers had exfiltrated customer payment data instead of running charges, the consequences would include breach notification obligations, regulatory exposure, and a trust deficit that no refund can fix.

The fix is not complicated. Check your frontend code. Check your repositories. Rotate anything exposed. Move secrets to the server. The entire process takes an afternoon. The cost of not doing it is unbounded.

Run a free surface scan

Talon checks your public GitHub repositories for committed secrets, your frontend for exposed API keys, and your server for accessible credential files. Passive, read-only, no account required.

A Founder Lost $2,500 Because His AI-Coded App Shipped a Stripe Secret Key in the Frontend | Talon