vibe-supabase-rls-disabled
| Category | Default severity | Lifecycle | Default confidence |
|---|---|---|---|
| security | BLOCKER | experimental | 0.85 (clamped to 0.6 while experimental) |
What it catches
CREATE TABLE statements in SQL files that are not paired with ALTER TABLE ... ENABLE ROW LEVEL SECURITY in the same file.
Why it matters
The Supabase anon key is shipped to the browser. Any reader of the bundled JavaScript can use it to read or write rows in tables that have no Row Level Security policy.
- CVE-2025-48757 (March 2025, CVSS 9.3) affected 170+ production Lovable apps in a single weekend through this exact class of bug.
- A community audit of 50 vibe-coded apps found 70% had RLS completely disabled (DEV, 2026).
- The Lovable EdTech leak exposed 18,697 student records, including 4,538 university accounts.
If you ship a Supabase table without RLS, the anon key in your client bundle is effectively a public read/write API for that table.
Example: failing code
create table profiles (
id uuid primary key,
user_email text not null
);The rule reports a BLOCKER on the create table line.
Example: how to fix
create table profiles (
id uuid primary key,
user_email text not null
);
alter table profiles enable row level security;
create policy "users read own profile"
on profiles for select
using (user_email = auth.jwt()->>'email');
create policy "users update own profile"
on profiles for update
using (user_email = auth.jwt()->>'email');Two things matter:
ENABLE ROW LEVEL SECURITYturns RLS on. Without a policy, all access is denied — that is safe but unusable.- Add at least one
CREATE POLICYthat scopes rows to the authenticated user. Do not use `USING (true)` — that is equivalent to having no RLS.
Known limitations
This rule scans one file at a time. If you enable RLS in a later migration file (for example 002_security.sql), this rule will still flag the create table from the earlier migration.
Workarounds:
- Recommended: enable RLS in the same migration that creates the table. It is the safer pattern anyway — a deploy that runs the create migration but fails the RLS migration leaves the table publicly readable.
- If you must split them, suppress the rule for that file:
sql /* codemore-ignore-file: vibe-supabase-rls-disabled */
Cross-migration analysis will land when the registry exposes a project-wide context API (tracked under the registry roadmap).
Suppression
-- codemore-ignore: vibe-supabase-rls-disabled
create table public_announcements (id uuid primary key, body text);Or file-wide:
/* codemore-ignore-file: vibe-supabase-rls-disabled */The suppression parser recognises -- (SQL), # (Python/shell/YAML), and // (JS/TS) as single-line comment leaders, and /* ... */ for file-wide directives across all languages.
How to verify the fix
The rule's verificationCriteria (read by the AI agent applying the fix) require:
- Migration file contains
ALTER TABLE <name> ENABLE ROW LEVEL SECURITY(case-insensitive). - At least one
CREATE POLICYexists for the table. - Re-scan reports
vibe-supabase-rls-disabledresolved for the file.
References
- Supabase: Row Level Security
- CVE-2025-48757
- VibeEval — Lovable Security Report, Feb 2026
- DEV — I Audited 50 Vibe-Coded Apps. Here's What Broke.