Check whether your Lovable app is leaking data
Lovable builds a working Supabase backend in an afternoon. What it does not do reliably is write the policies, and a table without policies is a table the internet can read.
Paste your app URL. RowShield reads your deployed bundle for the Supabase URL and anon key, asks PostgREST which tables it exposes, and tries to read one row from each — using exactly the access an attacker already has.
Rules that check this
- criticalTable readable with the anon key
ANON_TABLE_READABLE - criticalRow Level Security disabled
RLS_DISABLED - criticalservice_role key shipped to the browser
SERVICE_ROLE_KEY_EXPOSED
What the check proves
If rows come back, that is not a warning, it is a demonstration. The report names the table, the columns exposed, and the number of rows the anon role can see.
Row values are never retained. Column names and a count prove the exposure and carry none of the data.
What a clean result does and does not mean
An empty result is honest about its own ambiguity. PostgREST answers `200 []` both for "RLS filtered everything out" and for "the table is empty", so an empty table is reported as reachable, not as leaking.
A clean probe also says nothing about your write policies — nobody is going to insert rows into your database to prove a point. Connecting the project runs the full catalog audit, which covers writes.
Then stop it happening again
The failure mode with AI builders is not the first mistake, it is the fourth. Every prompt that touches the schema can drop a policy or add a table without one.
Continuous monitoring diffs each scan against the last and alerts on the transition — something appearing, or coming back after being fixed — rather than re-sending the same list every hour.
Reading the report, field by field
Each finding names the rule that fired, the exact table involved, and — for readable tables — the columns exposed with a row count. The column list is the part worth reading closely: it distinguishes a harmless lookup table from your profiles table leaking email addresses, and it does so without ever showing a single value.
Severity maps to impact rather than drama. A world-readable profiles table is critical because identity data enables phishing and correlation attacks; an empty-but-reachable table stays flagged as reachable because PostgREST cannot prove emptiness from outside. Warnings carry the probe's honest ambiguities instead of hiding them.
Remediation SQL arrives generated from your actual schema: enable-and-force lines plus owner-scoped policies using your real column names, ready to paste into the SQL editor. After applying, re-run the probe — findings transition to resolved in the next scan, which is the quiet proof the fix held rather than a claim that it did.
The check is also cheap enough to run repeatedly across your deploy surface. Production, preview deployments, and that staging project everyone forgot all expose different bundles and catalogs; a URL is the only input, so each can be probed in seconds after every meaningful release. Teams adopting this rhythm stop treating security review as an event and start treating it as telemetry — always on, always current, and alerting only when the picture changes. It also changes the conversation with teammates: instead of re-litigating whether a table is safe, paste the report link and argue about the fix.
Frequently asked
- Do I need to sign up?
- No. The public check needs a URL and nothing else.
- Will this modify anything?
- It cannot. Only GET, HEAD and OPTIONS are ever issued, enforced in code rather than by policy.
- What about Bolt, Cursor, v0 and Claude Code?
- Identical. The check reads a deployed site and a Supabase project; it does not care what generated them.
Check your project in about ten seconds
Paste a URL. No signup, no writes, nothing stored.
Run the free audit