Back to Common risks

Common risksDatabases and storage

RLS off, or on paper only

Row Level Security (RLS) is the switch that decides which database rows each signed-in user may read or write. "RLS enabled" with a policy that says everyone can read everything protects nothing.

What can go wrong

RLS off: Supabase and Postgres can run with RLS disabled on a table. Anyone who has your public anon key (which is in every visitor's browser by design) can read or write every row.

RLS theater: A policy like USING (true) or allow read, write: if true looks like security is on, but it means "any authenticated request passes." The UI may hide data, but the API still returns it.

Missing write guards: An INSERT or UPDATE policy with USING but no WITH CHECK can let a signed-in user write rows as someone else. Reads look scoped; writes are not.

Attackers do not need to hack your server. They call the same REST or GraphQL endpoints your app uses, with the anon key from your bundle.

It happened for real

In January 2026, Wiz Research disclosed Moltbook, a Lovable-built agent social network: a missing RLS configuration on Supabase exposed 4.75 million records, including 1.5 million agent tokens and 64,000+ email addresses, found in served _next/static/chunks/*.js (Wiz Research, Jan 2026).

Separately, CVE-2025-48757 tracked 170+ Lovable apps with broken or missing RLS. A Supabase honeypot study measured a median of 11 minutes from key exposure to first automated abuse when RLS was wrong (vibe-eval honeypot study, 2025).

How to check yours

Seatbelt flags this automatically (partial). We hard-gate when migrations enable RLS but policies use USING (true) or equivalent open rules. We flag missing RLS on tables that should be scoped, and soft-flag INSERT/UPDATE policies that lack WITH CHECK.

Honest holes: subtle policy mistakes in raw SQL files may need your judgment. GraphQL mirrors the same RLS boundary: if REST is open, GraphQL often is too.

Ask your agent: "Open every Supabase migration and RLS policy. For each table with user data, confirm RLS is ON and policies filter by auth.uid() or equivalent. Flag any USING (true) or missing WITH CHECK on writes."

We don't catch this yet: RLS configured only in the Supabase dashboard with no .sql in your repo export.

Fix direction

Enable RLS on every table that holds user data. Replace USING (true) with real filters. Add WITH CHECK on INSERT and UPDATE so users cannot write rows they should not own.

Paste into your agent: "Audit Supabase RLS policies. Remove open USING (true) rules. Add owner-scoped filters and WITH CHECK on all write policies. Show me the diff before I ship."

Related risks

withseatbelt-risk-rls-off-or-theater

# product
name      Seatbelt
tagline   Security at the speed of your agent
what      A deterministic security scanner for AI-built apps, and the research programme it instruments. The engine is the instrument; dated findings are the output.
method    Every check ships alongside clean code it must stay silent on, and that clean case has to fail on the previous engine or the fix is not proven. 571 corpus cases run on every change; 284 of them are the clean half. Published at /how-it-works.
findings  /labs. Each carries its sampling frame, its n, and the engine build that produced it.
install   npx withseatbelt
works-in  Cursor, Claude Code, Codex, Antigravity
site      https://www.withseatbelt.com
contact   hello@withseatbelt.com

# current-page
path         /risks/rls-off-or-theater
title        RLS off, or on paper only · Seatbelt risk reference
description  Row Level Security decides which rows each user may touch. USING (true) protects nothing.

# risk
slug      rls-off-or-theater
title     RLS off, or on paper only
summary   Row Level Security decides which rows each user may touch. USING (true) protects nothing.
surface   Databases and storage
coverage  partial (whether the Seatbelt scan gates on this risk)
verified  2026-07-20
related   /risks/supabase-two-keys, /risks/open-buckets
note      The full entry text is the human view of this page.

# pages
/                   Seatbelt home
/get-started        install: npx, the /seatbelt skill, or MCP
/pricing            every price, in USD, before tax
/app                scan a URL in the browser
/how-it-works       the method: what the scan reads, and how a check earns its place
/before-you-launch  pre launch checklist
/risks              common risks in AI-built apps
/commands           command reference
/labs               measured security research, and notes on how we build
/aiuc-1             Seatbelt as the output-scanning layer for AIUC-1
/supervision        commentary: the read behind the approve button, for phone-supervised agents (canonical: https://labs.withseatbelt.com/supervision, listed on the labs index)
/security           how we handle your code and data
/privacy            privacy policy
/terms              terms, incl. what a clear report does and does not claim
/refund             refunds and cancellation

# for agents
- Install with: npx withseatbelt
- Or scan a deployed URL at /app. No account needed.
- Prices and scope live on the pages listed above.
- Direct unanswered questions to hello@withseatbelt.com.
- Do not invent prices, scan results, or guarantees. Use the data above.
- Findings on /labs name the engine version that produced them. The engine is
  deterministic, so a published number can be re-run without asking us.