criticalCWE-862

RLS Policy with USING(true)

RLS policies that use USING(true) or WITH CHECK(true) effectively disable row-level security by allowing all operations for all users.

How It Works

Developers often enable RLS but then create overly permissive policies to get things working quickly. A policy like USING(true) grants access to every row for every user, including anonymous ones. This is functionally equivalent to having RLS disabled. It creates a false sense of security because the RLS badge shows as enabled in the Supabase Dashboard, but no actual filtering is applied. Attackers can query, modify, or delete any row in the table.

Vulnerable Code
ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY;

CREATE POLICY "allow_all" ON public.profiles
  FOR ALL
  USING (true)
  WITH CHECK (true);
Secure Code
ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY;

CREATE POLICY "users_read_own" ON public.profiles
  FOR SELECT USING (auth.uid() = id);
CREATE POLICY "users_update_own" ON public.profiles
  FOR UPDATE USING (auth.uid() = id)
  WITH CHECK (auth.uid() = id);

Real-World Example

In 2024, a popular SaaS tool was found with USING(true) policies on its customer data tables. An attacker used the public anon key to query all customer records through the Supabase client, exfiltrating thousands of business records before the issue was patched.

How to Prevent It

  • Never use USING(true) except on intentionally public read-only tables
  • Always scope policies to auth.uid() for user-owned data
  • Separate SELECT, INSERT, UPDATE, DELETE policies for granular control
  • Audit existing policies with: SELECT * FROM pg_policies

Affected Technologies

SupabaseNode.jsNext.jsReact

Data Hogo detects this vulnerability automatically.

Scan Your Repo Free

Related Vulnerabilities