Mesrai
Back to blog
// essaySecurity

The Hardcoded API Key Mesrai Found in a Test Fixture

Real PR catch: a Stripe live key hardcoded in a test fixture. Mesrai's flag, the rotation procedure, and the pre-commit hook that closes the class. CWE-798.

Mesrai TeamSeptember 20, 20268 min read

A unit test for the payments module. Author needed a Stripe key to make the fixture work. Pasted the live key in 'just for now'. Mesrai flagged it 40 seconds after the PR opened — the secret was already in git's permanent record by that point.

The vulnerable diff

tstests/fixtures/payment.ts
// tests/fixtures/payment.ts
export const STRIPE_KEY = "sk_live_51HZ3aBC9DEfGhIjK...4MzNa";

export const fixturePayment = {
  amount: 1000,
  currency: "usd",
  source: "tok_visa",
};

What is wrong

Once a secret is committed to a public or shared git repo, it is permanently in the history. Force-pushing over the commit does not help — GitHub caches dangling commits, and any clone made before the rewrite still has the secret. CWE-798 covers hardcoded credentials of every form. The fix is twofold: rotate the secret at the provider so the leaked value no longer works, then update the code to read from a runtime secret store.

The attack

An attacker scraping public commits can find this within minutes — GitHub's commit feed is indexed by services like trufflehog and gitleaks within hours of push.

bashexploit
# Public scrapers find leaked Stripe keys within hours
trufflehog github --repo https://github.com/org/repo --since-commit HEAD~50
# Finds: STRIPE_KEY entropy 5.2 — likely Stripe live key
# Stripe Radar will also notify the account owner, but not before the
# attacker has had a chance to make API calls.

Result: unauthorized charges, customer refunds, account suspension from Stripe — and a forensics exercise on every transaction since the leak.

Mesrai's review comment

textreview-comment.txt
mesraipilot · Bot · reviewed 40 sec ago

[mesrai] [code-review] [Security] [CWE-798] [critical]

Hardcoded Stripe live key (`sk_live_*` prefix). This must not merge.
Even if the PR is rejected, the secret is already in git's local
history — rotate the key in the Stripe dashboard now.

Steps:

  1. Roll the key at https://dashboard.stripe.com/apikeys
  2. Update production env to the new value
  3. Remove the key from the test fixture; read from
     process.env.STRIPE_SECRET_KEY instead
  4. Add a pre-commit secret-scan (gitleaks/trufflehog) so this
     does not recur

Reference: CWE-798, OWASP Cheat Sheet — Secrets Management

The fix

tstests/fixtures/payment.ts (fixed)
// tests/fixtures/payment.ts — fixed
export const STRIPE_KEY = process.env.STRIPE_TEST_KEY;
if (!STRIPE_KEY) throw new Error("STRIPE_TEST_KEY required for tests");

// Use Stripe TEST keys (sk_test_...) in test fixtures, never LIVE
export const fixturePayment = { amount: 1000, currency: "usd", source: "tok_visa" };

Two changes. Read from environment variable so the test still runs in CI with the test key. Use Stripe's `sk_test_*` keys for tests — they cannot charge real cards. Add a pre-commit hook (gitleaks) so any future hardcoded secret gets caught at the laptop, not at review.

Why human review missed it

The fixture file looked test-only. Reviewers' eye slid past the string because it was in a file named 'fixtures'. Mesrai's rule pack does not weight by directory — every string with `sk_live_`, `AKIA`, `AIza`, or other known secret prefixes is flagged regardless of location.

Related rules + further reading

Mesrai rule pack: security/no-hardcoded-secrets — flags strings matching known credential patterns or high-entropy substrings.

OWASP: Secrets Management Cheat Sheet.

CWE-798 — Use of Hardcoded Credentials. Top of every cloud-security report year over year.

Takeaway

Test fixtures are not a safe place for secrets. Use test-mode keys read from env vars. Add a pre-commit secret scan today — the cost of a leaked live key always dwarfs the setup time.

// try

See it on your next PR.

Free for individuals. Install in two minutes. Mesrai reviews every commit.