Heimdall Scan logo, AI security scanner for vibe coders
Heimdall ScanOpen Beta
CriticalAccess Control

Missing row-level security on your Supabase or Firebase database

Row-level security (RLS) is a set of rules on your database that decide which rows a given request is allowed to touch. Supabase and Firebase both ship with RLS off or wide open by default, which means the client-side key your app already exposes to the browser can query the entire table unless you lock it down.

#What goes wrong

AI coding tools set up the database schema and the client connection, but RLS policies are a separate manual step that's easy to skip, especially since the app works fine in testing with a single account. Nothing breaks until someone opens dev tools and points a request at another user's data.

#Why it matters

The public anon key that ships in your JS bundle is, by design, visible to anyone who opens your site. If RLS isn't enabled, that key is enough to read or write any row in any table: other users' profiles, private messages, payment records, everything.

#How Heimdall checks for this

Heimdall looks at your Supabase or Firebase setup and checks whether row-level security is enabled on your tables, and whether the policies that exist actually scope rows to the requesting user instead of allowing all access.

#How to fix it

In Supabase, enable RLS on every table from the dashboard or a migration, then add a policy like auth.uid() = user_id for row ownership. In Firebase, write security rules that check request.auth.uid against the document owner. Test with a second account to confirm you can't see the first account's data.

Frequently asked questions

Does RLS slow down my queries?

I use the service role key on the server. Do I still need RLS?

Is RLS on by default in a new Supabase project?

Run this check on your own repo

Heimdall scans your GitHub repo for this and 29 other issues in under a minute.