Impact
Attackers can bypass application logic to read, update, or delete records in the database if Row Level Security (RLS) is not properly enforced [S1]. This often results in the exposure of Personally Identifiable Information (PII) or sensitive application data to users who only have access to the public anonymous API key.
Root Cause
Supabase uses Postgres Row Level Security to manage data access at the database level, which is fundamental for securing data [S1]. In a Next.js environment, developers must create a Supabase client that correctly handles cookies and sessions to maintain security during server-side rendering [S2]. Vulnerabilities typically arise when:
- Tables are created without RLS enabled, making them accessible via the public anon key [S1].
- The Supabase client is misconfigured in Next.js, failing to properly pass user authentication tokens to the database [S2].
- Developers accidentally use the
service_rolekey in client-side code, which bypasses all RLS policies [S1].
Concrete Fixes
- Enable RLS: Ensure Row Level Security is enabled for every table in your Supabase database [S1].
- Define Policies: Create specific Postgres policies for
SELECT,INSERT,UPDATE, andDELETEoperations to restrict access based on the user's UID [S1]. - Use SSR Clients: Implement the
@supabase/ssrpackage to create clients in Next.js that correctly manage server-side authentication and session persistence [S2].
How FixVibe tests for it
FixVibe already covers this through deployed-app and repo checks. The passive baas.supabase-rls module discovers Supabase URL and anon-key pairs from same-origin JavaScript bundles, asks PostgREST for public table metadata, and performs limited read-only selects to confirm anonymous data exposure without mutating customer data. Repo scans also run repo.supabase.missing-rls to flag SQL migrations that create public tables without ENABLE ROW LEVEL SECURITY, and secret scans look for service-role key exposure before it reaches the browser.
