DEV Community

Perufitlife
Perufitlife

Posted on • Originally published at github.com

I scanned 30 Supabase repos this morning and found 3 production-grade leaks (one with service_role committed)

TL;DR

This morning I ran a wider sweep of public GitHub repos that import @supabase/supabase-js and have anything resembling an anon key (or worse, a service_role key) in committed code.

Out of ~30 repos I probed (responsibly — counts only, no row contents), three had production-grade leaks:

  • A Chinese AI paper-writing tool with 1,669 stars and 1,843 user profile records readable anonymously.
  • Two indie-SaaS repos with the service_role key committed to .env.local — meaning anyone who finds the repo can read/write/delete every row in their database.

All three got responsible-disclosure pings (private email or GitHub issue) with a free DIY fix walkthrough + a paid turnkey option. We'll see what happens.

This post is about the method + monetization frame, not naming specific projects. If you want to scan your own project, the CLI is open source: @perufitlife/supabase-security.

The method (90 seconds per repo)

# 1. Fetch the file that imports createClient
curl -sL "https://raw.githubusercontent.com/<owner>/<repo>/main/path/to/file.ts"

# 2. Grep for hardcoded URL + key (most repos use env vars properly,
#    but ~10% commit a fallback or a .env.local for "convenience")
grep -oE 'https://[a-z0-9-]+.supabase.co'
grep -oE 'eyJ[A-Za-z0-9_-]+.eyJ[A-Za-z0-9_-]+.[A-Za-z0-9_-]+'

# 3. Probe common table names with the anon key — counts only, no data
curl -sLI "$URL/rest/v1/profiles?select=*"   -H "apikey: $KEY" -H "Authorization: Bearer $KEY"   -H "Prefer: count=exact" -H "Range: 0-0"   | grep -i "content-range"

# Output like: Content-Range: 0-0/1843
# Means: 1843 profile records readable by anyone with the anon key
Enter fullscreen mode Exit fullscreen mode

That's it. No clever exploitation, no zero-days. Just: did the repo commit a key, is RLS on, what's the count.

What % of repos are leaking

Across the ~30 I tested today:

  • ~10% had a hardcoded URL + working anon key. Most do this as a fallback in code (process.env.X || 'hardcoded').
  • ~50% of those had RLS disabled on at least one user-data table (profiles, users, accounts, etc.).
  • 2 had service_role keys committed. That's the catastrophic one — bypasses ALL RLS.

So the back-of-envelope hit rate for "find a real leak" is around 1-in-15 to 1-in-30 repos. Not high enough to spray-and-pray, but high enough that targeted searches (specific stacks, specific verticals) yield gold.

The monetization side

For folks building security tooling — the play I'm running:

1. Differential pricing by severity. A toy project hobbyist gets the free DIY walkthrough. A 1k-star app with paying Pro users gets pitched a $249 written audit + attestation. A B2B SaaS with service_role leaked gets pitched a $499-999 incident-response package.

2. Recurring monitoring upsell ($29/mo). One-time fix = $99. Continuous monitoring with weekly diff scans = $348/yr. The math favors recurring.

3. Bug bounty programs. Check HackerOne, BugCrowd, Intigriti for the target's name before doing free disclosure. Verified critical findings pay $500-10K. (None of my 3 today were on a bounty program.)

4. Vertical specialization. Healthcare app leaking patient data → HIPAA-adjacent compliance angle, different price tier. Finance app → PCI-DSS angle. Education → FERPA. Same scan, different anchoring.

5. Aggregated SEO posts (this one). Each scan batch becomes a post. Each post drives inbound. The compound is the brand, not the individual sale.

6. Stack expansion. Same pattern works on Firebase (firebase-security package), PocketBase, Appwrite, Nhost. We have all 5. Each new stack = new search surface area.

7. Cyber-insurance affiliate. Some insurers underwrite SaaS cyber policies and need risk signal pre-issue. Each verified leak finding can be sold as risk-assessment data ($50-200 per lead) to the right broker.

The ethical line I'm holding: never read row data, never publish identifying info pre-disclosure, always give a free DIY fix path. The paid offer is for the people who'd rather pay than learn the SQL. Both paths fix the leak. That's the actual goal.

What I'm doing next

  • Expanding the scanner search to Bolt + Lovable + Replit "vibe-coded" Supabase apps. Reddit reports 33% RLS issue rate on those. Lower-conversion targets (mostly toy projects) but easier to scale.
  • Same pattern on Firebase / PocketBase / Appwrite. Already have the scanners (Perufitlife on npm).
  • Weekly RLS Monitor — $29/mo that re-scans your project and alerts you on the first new leak. rls-monitor.vercel.app.

If you've shipped a Supabase project to production and never explicitly written RLS policies on every table, you are most likely in the ~50% that leaks. Free CLI scan takes 5 minutes: npx @perufitlife/supabase-security --discover (your keys never leave your terminal).

If you'd rather pay someone to do the audit + write the policies turnkey, $99 (one-time): stripe link.

— Renzo (perufitlife on GitHub / npm)

Top comments (0)