PL-018lowCode

Sign-ups need no email confirmation

Anyone can create a working account with any email address, including one they don't own.

Severity
Low
Who can exploit it
Anyone
Found by
PatchLabs Code: supabase/config.toml
Lab proof
Not lab-proven: file and line in the report

What it is

With email confirmation off, signUp() returns a working session straight away, for any address typed in. The account works before anyone proves they own the inbox. On its own that is a product decision, which is why this finding is low severity. It becomes a security problem in two situations:

  • Access decided by email. A policy or admin check such as (auth.jwt() ->> 'email') like '%@yourco.com' is passed by signing up with any new address at that domain. An allow-list of addresses is passed by signing up with one that hasn't registered yet.
  • Rules that trust "signed in". Every PL-002 and PL-012 becomes reachable by a script creating throwaway accounts with no inbox behind them.

Why AI builders produce it

Confirmation emails need an email provider and slow down testing, so they get switched off during development. The local supabase/config.toml created by the Supabase CLI has confirmations off by default, and that file reaches a hosted project if someone pushes the config.

Example of vulnerable code

Simplified from the patterns we see in AI-built apps. Synthetic: not taken from any real app.

supabase/config.toml (vulnerable)
# supabase/config.toml
[auth.email]
enable_signup = true
enable_confirmations = false
supabase/migrations/…_staff.sql (vulnerable)
-- ...together with a policy that trusts the email claim
create policy "Staff read all orders"
  on public.orders for select to authenticated
  using ((auth.jwt() ->> 'email') like '%@yourco.com');

Check it yourself

Check the hosted project first: in your Supabase dashboard's authentication settings, the Email provider's Confirm email option should be on. Hosted projects start with it on. Then check the repo and your policies:

check-pl-018.sh
# In the repo
grep -n "enable_confirmations" supabase/config.toml
check-pl-018.sql
-- Policies that decide access from an email address
select tablename, policyname, qual, with_check
from pg_policies
where coalesce(qual, '') ilike '%email%'
   or coalesce(with_check, '') ilike '%email%';

The fix

supabase/config.toml (fixed)
# supabase/config.toml
[auth.email]
enable_confirmations = true

And decide staff access from a table you control, not from what an address looks like:

supabase/migrations/…_fix_staff.sql
drop policy "Staff read all orders" on public.orders;
create policy "Staff read all orders"
  on public.orders for select to authenticated
  using (exists (
    select 1 from public.user_roles r
    where r.user_id = (select auth.uid()) and r.role = 'staff'
  ));

Code findings come with the file, the line and a one-line fix in the report, for your engineer to make. PatchLabs never pushes to your repo.

How PatchLabs finds it

code scan · report excerpt
[SCAN]    supabase/config.toml:42
          [auth.email]
          enable_confirmations = false LEAK
[FIX]     confirm email in config
          and in the dashboard
synthetic exampleReport excerpt · read from the repo, not lab-proven

PatchLabs reads your repo only, so it sees supabase/config.toml, not the live setting in your hosted project. When the file says confirmations are off, the report asks you to check the dashboard too. If the file is missing, there is nothing to flag, but the dashboard setting still matters.

When the pattern is intended

Fine for apps where an account holds nothing private and no access depends on the email address. Apps that sign in only with magic links or OAuth prove inbox or account ownership at every sign-in anyway.

Why it’s rated low

Low, because it exposes nothing by itself. It raises the stakes of other findings: with no confirmation, "anyone who signs up" means anyone with a script, using any address.

Free check

Does your app have PL-018?

Paste your public repo. PatchLabs Code reads it for this and every other code finding, and the Lab rebuilds your database to test who can read what.

Free for your first appReads your public repo onlyOr run the free static RLS check

Last reviewed 10 Nov 2026. Finding IDs are stable: link to them freely. Spotted a mistake? Tell us.