Research·11 min read

20 Million Rows Exposed: A Supabase Security Study of YC Startups

We scanned 107 Y Combinator startups using Supabase and found alarming security gaps. 28% were exposing PII through misconfigured databases. Here's what we discovered and how to protect your data.

Victor

Victor

20 Million Rows Exposed: A Supabase Security Study of YC Startups

Key Findings

Over a two-week period, we conducted an automated security assessment of Y Combinator startups using Supabase as their backend. The results were concerning:

  • 107 YC companies identified using Supabase
  • 71 companies with accessible databases audited
  • 20.1 million rows of data exposed to anonymous access
  • 20 companies (28%) leaking personally identifiable information (PII)
  • 3 companies exposing authentication tokens or session data

This research was conducted responsibly through coordinated disclosure with both the Y Combinator and Supabase security teams.

Why This Research Matters

Supabase has become the go-to backend for modern startups. Its PostgreSQL foundation, real-time capabilities, and developer-friendly APIs make it incredibly powerful. Y Combinator companies, known for moving fast and shipping quickly, have embraced it enthusiastically.

But with that speed comes risk.

Supabase's security model relies heavily on Row-Level Security (RLS) policies. When configured correctly, RLS ensures that users can only access data they're authorized to see. When misconfigured—or simply forgotten—databases become publicly accessible to anyone with the anonymous API key.

And here's the thing: that anonymous key is always exposed in your frontend code. It's meant to be public. The security comes from RLS, not from hiding the key.

Many developers don't fully understand this model. They assume the key provides some protection. It doesn't.


How This Attack Works

Many developers assume that if their application doesn't display certain data, it's protected. This is dangerously wrong.

How This Attack Works

Why hiding data in your UI doesn't protect it

Normal User
1

Visits your website

Opens app in browser

2

App queries database

Frontend filters: WHERE user_id = me

3

Sees their own data

5 rows returned

Attacker
1

Visits your website

Opens app in browser

2

Extracts credentials from JS

Fetches SUPABASE_URL + ANON_KEY

3

Queries database directly

No app filters: SELECT * FROM users

What the attacker gets depends on your RLS configuration

Without RLS

Database returns ALL 10,000 rows

The database doesn't know who's asking—it just gives everything.

With RLS

Database enforces same rules as your app

Anonymous user? 0 rows. Even direct queries are protected.

The key insight: your frontend decides what to show, but without Row-Level Security (RLS), your database decides what to allow—which is everything.

An attacker doesn't need special tools or skills. They simply:

  1. Visit your website
  2. Find your Supabase URL in the browser (it's in your JavaScript bundle, press F12)
  3. Make the same API calls your app makes, but without your app's filters

This isn't hacking. It's asking your database for data it's configured to give away.


Methodology Overview

We used Supabomb, our open-source Supabase security testing tool, to conduct this research. The methodology involved three phases:

  1. Discovery: Automated detection of Supabase usage across 107 YC company websites
  2. Enumeration: Assessment of what data was accessible via anonymous API access
  3. Classification: AI-powered severity analysis of exposed data types

From the initial 107 companies, we were able to analyze 71. The remaining 36 were mobile-only apps, disabled projects, or custom configurations that blocked anonymous access by design.

All testing was limited to read operations using publicly accessible anonymous credentials. No authentication bypass, no exploitation, no data exfiltration. Just checking what's already publicly available—the same thing any curious visitor or malicious actor could do.

For full details on Supabomb's capabilities, see our introduction post.


Severity Distribution

Vulnerability Severity Distribution

71 companies analyzed • 20,118,887 total rows exposed

Critical
8 (11.3%)14,425,679 rows
High
2 (2.8%)66,597 rows
Medium
10 (14.1%)7,330 rows
Low
23 (32.4%)5,619,281 rows
Safe
28 (39.4%)

The severity classification was based on the type of data exposed:

  • Critical (11%): Authentication tokens, passwords, payment data, or more than 100,000 PII records
  • High (3%): More than 1,000 PII records with emails or personal information
  • Medium (14%): Fewer than 1,000 PII records or restricted business data
  • Low (32%): Internal data without PII or authentication information
  • Safe (39%): All tables empty or properly protected by RLS

Only 28 out of 71 companies (39%) had properly configured their databases. The remaining 61% had some level of data exposure.


Scale of Exposure

Top 8 Most Exposed Databases

Anonymized companies ranked by total rows accessible without authentication

The numbers are staggering. A single education-focused startup exposed 8.5 million rows including student transcripts and email addresses. A consumer app leaked 4 million rows of browser state and authentication data.

These aren't theoretical vulnerabilities. This is real user data, sitting in publicly accessible databases, waiting to be discovered.


Industry Analysis

Affected Companies by Industry

Distribution of 71 companies across sectors

B2B
40 (56.3%)
Consumer
11 (15.5%)
Industrials
5 (7%)
Education
4 (5.6%)
Real Estate
4 (5.6%)
Healthcare
3 (4.2%)
Government
2 (2.8%)
Fintech
1 (1.4%)
Other
1 (1.4%)

B2B companies made up the largest portion of affected startups (50%), reflecting the overall composition of YC's recent batches. However, the most concerning exposures came from consumer and education companies, where the data involved end-users who had no idea their information was publicly accessible.

Healthcare companies, while fewer in number, represented some of the highest-risk exposures given the sensitive nature of medical data.


What Was Exposed

Types of Sensitive Data Exposed

Number of companies exposing each category of sensitive information

20
PII Exposure
3
Auth Tokens
0
Payment Data

The most common exposure was PII (Personally Identifiable Information)—email addresses, names, user profiles. This was found in 20 companies (28% of those audited).

More concerning, 3 companies (4%) were exposing authentication-related data: session tokens, API keys, or OAuth credentials. This isn't just a privacy issue—it's a direct path to account takeover.

No companies were exposing payment card data—but this is largely because startups outsource payment processing to providers like Stripe, which handle card data in their own PCI-compliant infrastructure. The sensitive data never touches the Supabase database in the first place.


Trend Over Time

Vulnerability Distribution by YC Batch

How security posture varies across Y Combinator cohorts

Note: Recent batches show higher counts due to increased Supabase adoption

Recent YC batches show higher numbers of Supabase adoption—and higher absolute numbers of vulnerable companies. This reflects Supabase's rapid growth as the default backend choice for new startups.

The proportion of companies with data exposure remains relatively stable across batches at around 55-65%. This suggests that security awareness hasn't significantly improved despite Supabase's growing documentation and tooling—highlighting the need for better defaults and automated security checks.


Root Causes

Why does this happen? Based on our analysis, two primary patterns emerged:

1. Missing RLS Policies on New Tables

The most common issue. Developers create tables, build features, and ship to production—without ever enabling RLS. Supabase allows this by design (you shouldn't need security in development), but it's dangerous in production.

-- This table has NO protection
CREATE TABLE users (
  id uuid PRIMARY KEY,
  email text,
  full_name text
);

-- Anyone with the anon key can:
-- SELECT * FROM users;

This is especially problematic when adding new features to an existing application. The original tables might have RLS configured, but new tables created for a feature often don't—creating security gaps that widen with every release.

2. No Security Review in Development Process

The deeper issue isn't technical—it's process. Most teams don't have RLS policy review as part of their development workflow:

  • No PR checklist item for "Did you add RLS policies to new tables?"
  • No automated checks that flag tables without RLS in staging/production
  • No security review when database schema changes are deployed
  • No periodic audits of what data is accessible anonymously

The fix isn't just enabling RLS once—it's building security checks into your CI/CD pipeline and code review process. Every migration that adds a table should require explicit RLS policy decisions.

3. Storing Secrets in Plain Text

A hidden risk we discovered: companies storing plaintext API keys and third-party authentication tokens directly in database tables. This is dangerous because:

  • Anyone who can read the table gets access to your integrations (Stripe, SendGrid, OpenAI, etc.)
  • Compromised keys can lead to cascading breaches across services
  • API providers may hold you liable for unauthorized usage

Solution: Use Supabase Vault to encrypt sensitive values at rest. Vault provides column-level encryption for secrets like API keys, tokens, and credentials—ensuring they remain protected even if table access is misconfigured.


Disclosure Process

We followed responsible disclosure practices throughout this research, working directly with the Y Combinator and Supabase security teams to coordinate remediation:

  1. Initial Contact: Reported findings to YC Security and Supabase Security teams
  2. Company Notification: Both teams helped facilitate outreach to affected companies
  3. Technical Details: Provided clear documentation of affected tables and data types
  4. Remediation Guidance: Shared RLS best practices and specific fix recommendations
  5. Coordinated Timeline: Agreed on January 26, 2026 publication date to allow remediation

We'd like to thank the Y Combinator security team and the Supabase security team for their prompt response and coordination throughout this process. Their proactive engagement helped ensure affected companies received timely notification and remediation guidance.


Remediation Results

We rescanned all affected companies before publication. The results were mixed:

Remediation After Disclosure

Response from 41 notified companies • Rescanned before publication

Fully Fixed
6 (14%)
Partially Fixed
2 (5%)
No Change
29 (69%)
Worsened
4 (10%)
-5.8M
Fewer rows exposed
8.7M
PII rows still exposed

The good news: 5.8 million fewer rows are now exposed, and PII exposure dropped by 40%. The companies that acted moved quickly and decisively.

The bad news: 69% of notified companies made no changes. Four companies actually increased their exposure—one by over 2.8 million rows. And 8.7 million rows of PII remain accessible across the companies we studied.

Disclosure helps, but it's not enough. This is why we're advocating for better defaults and automated security tooling.


How to Check Your Own Application

If you're using Supabase, here's how to verify your security:

Supabase Dashboard

The easiest way to check is through the Supabase dashboard:

  1. Go to Database → Tables in your Supabase project
  2. For each table, check if RLS is enabled (look for the shield icon)
  3. Click on a table and go to Policies to see what access rules exist
  4. Pay special attention to tables without any policies—they're likely vulnerable

Supabase also provides the Database Linter which can identify common security issues.

Use Supabomb

For a comprehensive automated assessment, use our open-source tool Supabomb:

# Clone and run with uv (handles dependencies automatically)
git clone https://github.com/ModernPentest/supabomb.git
cd supabomb

# Discover Supabase credentials from your app (auto-saved for later commands)
uv run supabomb discover --url https://your-app.com

# Enumerate all accessible tables and row counts
uv run supabomb enum

# Run security tests on RLS, storage, and edge functions
uv run supabomb test --output report.json

Supabomb will identify:

  • Tables accessible without authentication (with row counts)
  • Storage bucket permissions
  • Edge function JWT requirements
  • Differences between anonymous and authenticated access

Essential RLS Checklist

  • RLS is enabled on ALL tables (ALTER TABLE x ENABLE ROW LEVEL SECURITY)
  • Every table has explicit policies for SELECT, INSERT, UPDATE, DELETE
  • New tables added in migrations include RLS policies
  • Service role key is NEVER in frontend code
  • Storage buckets have appropriate access policies
  • Security review is part of your PR/deployment process

What Supabase Is Doing About It

Credit where it's due: Supabase has been investing heavily in security tooling. Their 2025 security retrospective outlines significant progress:

Already shipped:

  • Security Advisors: AI-powered detection of RLS misconfigurations with one-click fixes
  • MCP server integration: Security checks directly in your IDE
  • Publishable keys: OpenAPI spec no longer exposed to anonymous users, preventing schema enumeration

Coming in 2026:

  • Grant toggles: Toggle API access per-table directly from the dashboard (currently in staging)
  • GraphQL disabled by default: Reducing attack surface on new projects
  • Security-focused test harness: Validate RLS policies before deploying to production

These are exactly the right investments. Based on our findings, the features that would have prevented the most exposures are:

  1. Grant toggles — Most developers don't realize their tables are exposed. A visual toggle makes the default state obvious.
  2. Security Advisors in CI/CD — Catching misconfigurations before they reach production, not after.
  3. Hardened project defaults — The upcoming "hardened project configurations" option could dramatically reduce exposure for security-conscious teams.

The gap between Supabase's security capabilities and actual developer adoption suggests a discoverability problem. The tools exist—they just need to be more prominent in the onboarding flow and deployment pipeline.


Conclusion

The startup ecosystem moves fast. YC companies are under pressure to ship, iterate, and grow. Security often takes a backseat to features.

But 20 million exposed rows is a wake-up call.

If you're building on Supabase—or any backend-as-a-service platform—security configuration is your responsibility. The defaults aren't secure. The documentation exists but isn't always followed. And the consequences of getting it wrong are real: user data exposure, regulatory violations, and loss of trust.

Take 30 minutes today to audit your RLS policies. Use Supabomb. Fix the gaps. Your users are trusting you with their data.


About This Research

This study was conducted by ModernPentest, a continuous penetration testing platform for modern SaaS applications. We specialize in security assessments for companies using Supabase, Firebase, Vercel, and other BaaS platforms.

If you'd like a comprehensive security assessment of your application—including API testing, authentication flows, and business logic vulnerabilities—get in touch.

All research tools used in this study are open source:

  • Supabomb - Supabase security testing
  • Full methodology available upon request for security researchers

Last updated: January 26, 2026

Written by

Victor

Victor

Founder, ModernPentest

ModernPentest

Ready to secure your application?

Get continuous, automated penetration testing for your Supabase, Firebase, or Vercel app. Start your first scan in under 5 minutes.