Product linePatchLabs Lab

Not a warning about your rules. A test of who can read your data.

Lint tools tell you a policy looks permissive. PatchLabs Lab rebuilds your database from its own migrations, queries it as an anonymous visitor, a signed-in stranger and the owner, and shows you the rows each one got.

Reads your public repo only · never connects to your live app or database

lab: three-identity probe, simplified
-- 1. anonymous visitor, with your public key
set local role anon;
select count(*) from public.profiles;   -- 2: LEAK
-- 2. signed-in stranger
set local role authenticated;
select set_config('request.jwt.claims', '{"sub":"<stranger>"}', true);
select count(*) from public.profiles;   -- 2: LEAK
The probe matrix from the real check of our demo app, 9 Nov 2026. Fake data. Open the full report.

How it works

From migrations to a reproduced leak, in a lab we throw away.

Every Lab finding is something we made happen, not something we guessed from reading SQL.

  1. Rebuild

    Your supabase/migrations run in a disposable Postgres with Supabase’s roles, auth functions and default grants.

    migrations applied roles: anon, authenticated
  2. Seed

    Fake rows for two test users in every table, so there is something to read and something to protect.

    2 users · fake rows no real data
  3. Probe

    Query each table as an anonymous visitor (your public key), a signed-in stranger and the owner.

    anon → 2 LEAK stranger → 2 LEAK owner → 1 OK
  4. Report

    Each leak becomes a finding with an ID, the columns exposed, who can read them and the evidence.

    PL-001 · critical public.profiles

Capabilities

8 Lab checks live today.

Each links to its finding page: the vulnerable pattern, how to check it yourself and the fix we write.

Findings library

Coming to Lab

Announced, not live. Each will appear in reports only once it ships and is tested. Until then they are not counted.

PL-019 (access decided by user_metadata) is live today as a Code check, which reads it from your code and SQL. Reproducing it in the lab comes later.

Sample output

What a Lab finding looks like.

The transcript from our demo app, then the finding it produced. Personal values are redacted before anything is stored.

Finding
PL-001 · Anonymous visitor can read personal data
Object
public.profiles · email, phone
Proof
anon read 2 rows, signed-in stranger read 2 rows
Severity
critical
Next
PatchLabs Fix writes and proves the migration
lab run · manra399/patchlabs-demo-app
[REBUILD] 1 migration → lab Postgres       OK
          Supabase roles, auth, default grants
[SEED]    2 test users, fake rows          OK
[PROBE]   as anon (your public key)
          select * from public.profiles;
          → 2 rows readable              LEAK
            email •••••@••••• phone +•• •••• ••••
[PROBE]   as stranger → 2 rows         LEAK
[PROBE]   as owner    → own row        OK
[FINDING] PL-001 · critical · public.profiles
leak foundReal run, 9 Nov 2026 · demo app, fake data

Why behaviour, not lint

A rule can look fine and still leak.

  • Read-only public tables show as intended, not as noise. If anyone may read your shop listings, mark them once and later checks remember.
  • Policies combine. Two harmless-looking policies can add up to “anyone can read”. The lab sees the result, not the parts.
  • Grants matter. We rebuild with Supabase’s default grants, so a table without RLS behaves exactly as it would in your project.
  • Owners must still work. Every probe includes the owner, so a “fix” that locks real users out is caught.

What the lab can’t see. It is only as complete as the migrations in your repo. Changes made by hand in the Supabase dashboard, or a backend other than Supabase/Postgres, are outside it, and the report says what couldn’t be rebuilt. It is not a pentest or a compliance certification.

Questions

Questions about this product line.

Something not covered? Email the founder.

Do you connect to my Supabase project?

No. We never need your database password or service key. The lab is a local Postgres rebuilt from the migrations in your public GitHub repo, seeded with fake rows and deleted after the run.

What if my migrations don’t build?

The report says which migration failed and what we couldn’t test. In our study, 318 of 436 repos rebuilt to a working database; the rest were mostly missing or out-of-order migrations.

How is this different from Supabase’s Security Advisor?

The advisor lints your live project’s settings, and it’s worth running. The lab tests behaviour: it signs in as each identity and counts the rows they get. Full comparison.

Are the five coming checks in my report?

No. PL-012 to PL-016 are announced so you know what’s next. They’ll appear in reports once they ship and are tested, and the changelog will say so.

Free check

Can a stranger read your users table? Find out in minutes.

Paste your public repo. You’ll get the leaks, the fix and the proof on one page.