Anon Key with Excessive Permissions
The anon database role has been granted permissions on too many tables, expanding the attack surface for anyone with the publicly available anon key.
How It Works
The Supabase anon key maps to the PostgreSQL anon role. By default this role has limited permissions, but developers often grant it access to many tables for convenience. Since the anon key is public (embedded in client-side JavaScript), excessive table permissions mean an attacker with just the anon key and project URL can query tables that should only be accessible to authenticated users or server-side code. Even with RLS, granting anon access to sensitive tables increases the risk of policy misconfiguration.
-- Granting anon access to everything
GRANT ALL ON ALL TABLES IN SCHEMA public TO anon;
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO anon;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO anon;-- Only grant anon access to specific public tables
GRANT SELECT ON public.blog_posts TO anon;
GRANT SELECT ON public.categories TO anon;
-- Authenticated users get more access
GRANT ALL ON public.profiles TO authenticated;
GRANT ALL ON public.documents TO authenticated;
GRANT ALL ON public.user_settings TO authenticated;Real-World Example
Security audits of Supabase projects frequently reveal that the anon role has been granted ALL permissions on every table. Combined with a single USING(true) policy oversight, this pattern has led to full database exposure in production applications.
How to Prevent It
- Only grant the anon role SELECT on intentionally public tables
- Use the authenticated role for user-specific data access
- Audit role permissions with: SELECT * FROM information_schema.role_table_grants
- Follow the principle of least privilege for all database roles
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.
Service Role Key Exposed
criticalThe 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.