Service Role Key Exposed
The Supabase service_role key is hardcoded in frontend code, committed to a repository, or exposed in client bundles, granting full database admin access to anyone.
How It Works
The Supabase service_role key bypasses all Row Level Security policies and grants full CRUD access to every table. When this key is exposed in frontend JavaScript bundles, public repositories, or client-side environment variables (NEXT_PUBLIC_), anyone can extract it from the browser DevTools or source code. With this key, an attacker can read, modify, and delete all data in the database, create or delete users, and access storage buckets — effectively becoming a database superuser.
// In a React component or Next.js client code
const supabase = createClient(
'https://abc123.supabase.co',
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIn0...'
);// Client-side: always use the anon key
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);
// Server-side only (API routes, server actions):
const supabaseAdmin = createClient(
process.env.SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!
);Real-World Example
In 2023, a security audit of open-source Supabase projects on GitHub revealed hundreds of repositories with service_role keys committed in plain text. Several production applications had their entire databases exfiltrated before the keys were rotated.
How to Prevent It
- Never prefix the service_role key with NEXT_PUBLIC_ or VITE_
- Only use service_role in server-side code (API routes, webhooks, cron jobs)
- Add Supabase keys to .gitignore and use environment variables
- Rotate keys immediately if they appear in any commit history
Affected Technologies
Data Hogo detects this vulnerability automatically.
Scan Your Repo FreeRelated Vulnerabilities
Row Level Security Disabled
criticalSupabase tables without RLS enabled allow any authenticated or anonymous user to read, insert, update, and delete all rows using the client library.
RLS Policy with USING(true)
criticalRLS policies that use USING(true) or WITH CHECK(true) effectively disable row-level security by allowing all operations for all users.
RLS Enabled Without Policies
highRLS is enabled on a table but no policies are defined, which silently blocks all access including legitimate queries from your application.
Public Storage Buckets
mediumSupabase storage buckets with overly permissive policies allow any user to upload, read, or delete files including other users' private documents and images.