← Back to VibeScan
CriticalSecurity Finding

Exposed Supabase Key in Page Source

VibeScan detected a Supabase API key embedded in your app's publicly visible JavaScript bundle. This is one of the most common — and most dangerous — issues we find in vibe-coded apps.

What we found

# Found in: /static/js/main.abc123.js
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
NEXT_PUBLIC_SUPABASE_URL=https://xyzcompany.supabase.co

Why this is critical

The Supabase anon key is intentionally public — that's fine in isolation. The danger is that Supabase uses this key to enforce Row Level Security (RLS). If you haven't enabled RLS on your tables, anyone with your anon key (everyone who visits your site) can run raw SQL against your database.

Real attack scenario: An attacker opens your site, copies the anon key from the JS bundle, and runs SELECT * FROM users against your Supabase URL. If RLS is off, they get every user record — emails, names, private data. This takes under 2 minutes.

Additionally, if you accidentally exposed a service role key (which bypasses RLS entirely), the attacker has full admin access to your database — reads, writes, deletes, all of it.

How to fix it

1

Enable Row Level Security on every table

In Supabase Dashboard → Table Editor → select each table → click "Enable RLS". Then add policies that restrict access to authenticated users only. This is the single most important step.

-- Enable RLS
ALTER TABLE users ENABLE ROW LEVEL SECURITY;

-- Allow users to only read their own data
CREATE POLICY "users_self_only" ON users
  FOR ALL USING (auth.uid() = id);
2

Never put the service role key in frontend code

The anon key is designed to be public. The service_role key is not — it bypasses all RLS. Keep it server-side only (API routes, server actions, edge functions).

// ✅ OK — anon key in frontend
const supabase = createClient(url, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY)

// ❌ NEVER in frontend
const supabase = createClient(url, process.env.SUPABASE_SERVICE_ROLE_KEY)
3

Audit your existing data for unauthorized access

Check your Supabase logs for unusual SELECT queries or large data reads. If RLS was off for any time in production, assume the data was accessible.

Fix prompt for Lovable / Bolt / Cursor

Copy and paste this into your AI tool:

“VibeScan found my Supabase anon key exposed in the JavaScript bundle. Please enable Row Level Security on all my Supabase tables and add policies so that users can only read and write their own data. Also confirm that the service_role key is never used in any client-side code — only in server-side API routes or edge functions.”

Check your app for this issue

VibeScan scans for exposed keys, missing RLS signals, CORS issues, and 8 more critical checks — in under 60 seconds.

Scan my app free →