When My Stripe API Key Got Leaked

Share

TL;DR

I accidentally committed my Stripe secret key to a public repo. Within 4 hours, someone had found it and started testing charges. Stripe's automatic key scanning caught it and disabled the key before any real damage happened. Total cost: $0 in fraud, but several hours of panic and a complete security overhaul of my workflow.

The Mistake

It was 11 PM on a Tuesday night. I was rushing to push a fix for a bug that was affecting customers. In my hurry, I created a quick test file to debug the Stripe integration locally. The file had my Stripe secret key hardcoded because I was "just testing."

"I'll remove it before I commit," I told myself. Famous last words.

Twenty minutes later, the bug was fixed. I ran my usual git add . and git commit. Then I pushed to the main branch. The deployment triggered automatically. I closed my laptop and went to bed, satisfied with a job well done.

The Discovery

The next morning, I woke up to three emails from Stripe:

  • An alert that my API key had been found in a public repository
  • A notification that the key had been automatically revoked
  • A security recommendation to rotate my keys immediately

My stomach dropped. I grabbed my laptop and opened GitHub. There it was, in plain text, in a file called test-stripe.js:

const stripe = require('stripe')('sk_live_actual secret key');

What Happened Next

11:23 PM (Previous Night)

I pushed the commit containing the exposed key to GitHub.

11:47 PM

GitHub's secret scanning detected the Stripe key and notified Stripe.

11:52 PM

Stripe automatically revoked the compromised key.

3:14 AM

Someone (likely a bot) attempted to use the key. It was already invalid.

7:30 AM

I woke up and saw the emails.

The Damage Assessment

I spent the next two hours reviewing everything:

  • Fraudulent charges: None. The key was revoked before anyone could use it.
  • Customer data accessed: Unknown, but unlikely given the timing.
  • Production impact: Yes. My app couldn't process payments until I added the new key.

The real damage was to my confidence. I thought I was careful. I had a .gitignore file. I used environment variables in production. But in one moment of rushing, I bypassed all of that.

Key insight: Most security breaches happen when we're tired, rushed, or "just testing." The times we let our guard down are exactly when mistakes happen.

What Saved Me

Three things prevented this from becoming a disaster:

  1. GitHub's secret scanning: GitHub automatically scans public repositories for known secret patterns and notifies the affected services.
  2. Stripe's automatic revocation: Stripe has a partnership with GitHub. When they're notified of an exposed key, they revoke it immediately.
  3. Quick turnaround: The whole process from commit to revocation took less than 30 minutes.

Without these automated protections, someone could have run up thousands of dollars in fraudulent charges on my account. Or worse, accessed customer payment information.

The Changes I Made

After this incident, I completely overhauled my workflow:

1. Pre-commit Hooks

I installed git-secrets and configured it to scan for API key patterns before every commit. If it finds something that looks like a secret, the commit fails.

2. Environment Variable Discipline

No more "just for testing" hardcoded keys. I created a .env.example file with dummy values and made it a habit to never put real credentials anywhere except environment variables.

3. Restricted API Keys

I started using Stripe's restricted keys feature. Instead of one key that can do everything, I create keys with only the permissions they need. My test key can't access customer data. My webhook key can only verify signatures.

4. Regular Key Rotation

Every 90 days, I rotate my API keys. It's a small hassle, but it limits the damage window if a key is ever compromised.

Lesson learned: Automation catches what humans miss. Pre-commit hooks, secret scanning, and automated revocation are not optional anymore. They're essential parts of any secure workflow.

What I Wish I'd Known

Looking back, there were several things I wish I'd understood earlier:

  • Git history is permanent: Even after I deleted the file, the key was still in my git history. I had to use git filter-branch to actually remove it.
  • Bots are fast: There are automated systems constantly scanning GitHub for exposed credentials. Minutes matter.
  • Test mode isn't safe either: Even test keys can be used to see your Stripe configuration and product information.
  • Stripe's partner program: Many secret providers (AWS, Google Cloud, Stripe) have partnerships with GitHub. They automatically revoke exposed keys, which is a huge safety net.

For Other Founders

If you're building with Stripe (or any API that involves money or sensitive data), please learn from my mistake:

  1. Set up pre-commit hooks today. It takes 10 minutes and can save you from disaster.
  2. Use environment variables from the start. Don't wait until you're "closer to launch."
  3. Enable GitHub's secret scanning. It's free for public repositories.
  4. Review your commits. Before pushing, run git diff --staged and actually look at what you're committing.

I got lucky. The automated systems protected me. But I don't want to rely on luck again.

What should I do if I've already exposed an API key?

Immediately rotate the key in your provider's dashboard. Then remove the key from your git history using git filter-branch or BFG Repo-Cleaner. Finally, check your account for any unauthorized activity.

Does GitHub scan all repositories for secrets?

GitHub scans all public repositories automatically. For private repositories, secret scanning is available on GitHub Advanced Security (paid) or free for select secret types on all repositories.

How quickly do attackers find exposed keys?

Research shows that exposed credentials on GitHub can be discovered within minutes. Automated bots constantly scan public commits for known secret patterns. This is why quick detection and revocation is critical.

What if my key was exposed but not used?

Rotate it anyway. You can't know for certain whether someone copied the key for later use. Once a secret is exposed, treat it as compromised and replace it immediately.

Don't Wait for a Scare

Scan your repository for exposed secrets before someone else finds them.

Start Free Scan
Security Stories

When My Stripe API Key Got Leaked