sixty

what it is for

Users can see each other’s data

Somebody signed in and saw a list that was not theirs — other people’s orders, other people’s messages. Or you have not seen it yet and the possibility has just occurred to you, which is the better moment to be reading this.

Why it is hard to see

This is the most serious defect these applications have and the quietest. A missing row-level security policy does not raise an error, does not slow anything down, and does not generate a support ticket from the person whose data was exposed — the page works, for everybody, showing everything.

It is also easy to arrive at honestly. Row-level security is off by default until you write a policy; a table added later does not inherit one; and a query written against your own account looks correct while you are the only user.

What Sixty does about it

Every query is checked for a specific shape: a table that holds one person’s data, no scoping condition anywhere in the statement — no user_id, org_id, tenant_id or auth.uid() — and more rows coming back than a single lookup would explain. All three have to hold before it says anything.

When they do, the finding names the query and the operation, and asks you to confirm rather than declaring a breach. A policy applied inside the database is not visible in the statement your app sent, so what this finds is a query that would be unsafe if RLS were missing — which is exactly the query to check when RLS is the thing most likely to be missing.

What it does not do

It cannot see your policies, only your statements, so it can be wrong in the safe direction: a query that is properly protected by a policy can still be flagged. It will not tell you whose data was exposed either — nothing about your users is collected, which is the same reason installing it adds nothing to your consent banner.

Related

Find out what your last change did.

Sign in
Supabase RLS missing: users seeing each other’s rows — Sixty