AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

Docs: RLS Guide GRANT Examples Are No-Op; TRUNCATE Bypasses RLS And Default Grants Expose It

The Supabase RLS documentation instructs users to grant SELECT/INSERT/UPDATE/DELETE to anon/authenticated after creating tables in the public schema, but these privileges are already granted by default. The actual required action—revoking the overbroad default grants—is missing. Additionally, TRUNCATE is included in the default grant and is not blocked by RLS, creating a silent security gap where authenticated or anonymous roles could wipe table data if a direct database path is available.

mediumConfidence 85%Supabase

Origin Analysis

Supabase's default privileges for the public schema grant ALL privileges (including TRUNCATE, REFERENCES, TRIGGER) on newly created tables to the anon and authenticated roles. PostgreSQL's Row Level Security does not apply to TRUNCATE statements, so even with RLS enabled and no policies, TRUNCATE succeeds. The documentation's grant-only examples are therefore no-ops and fail to alert users to the need to revoke dangerous privileges.
1. Create a new Supabase project and a table in the public schema without any explicit GRANT statements. 2. Query information_schema.role_table_grants for that table—observe anon and authenticated already have DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE. 3. Enable RLS on the table and do not create any policies. 4. Execute `SET LOCAL ROLE anon;` then `TRUNCATE table_name;`—the table is emptied despite RLS.

Fixing Code Block

-- Revoke all default privileges from anon and authenticated for an existing table REVOKE ALL ON TABLE <schema_name>.<table_name> FROM anon, authenticated; -- Grant only the necessary privileges GRANT SELECT ON <schema_name>.<table_name> TO anon; GRANT SELECT, INSERT, UPDATE, DELETE ON <schema_name>.<table_name> TO authenticated; -- Optional: change default privileges for future tables in public schema ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON TABLES FROM anon, authenticated;
The fix first revokes the overbroad default grants (including TRUNCATE, REFERENCES, TRIGGER) and then grants only the minimal set needed by PostgREST. The optional ALTER DEFAULT PRIVILEGES prevents new tables from inheriting the same excessive privileges. This aligns with the principle of least privilege and closes the TRUNCATE bypass.

Edge Case Audit

Executing REVOKE ALL on existing tables may break application functionality if app code or database functions relied on those privileges. Before applying, audit current usage and test in a staging environment. Rollback: re-grant the original privileges with `GRANT ALL ON TABLE <schema>.<table> TO anon, authenticated;` and remove any ALTER DEFAULT PRIVILEGES changes. Note that PostgREST does not expose TRUNCATE, but other pathways (direct connection, custom functions) may still be affected; always restrict database network access and review SECURITY DEFINER functions.

Ecosystem Topology