Back to Blog
ResearchMarch 20267 min read

We checked 50 Lovable apps' Supabase RLS. 43 were vulnerable.

We audited 50 Supabase-backed apps built with Lovable over a two-week period. The results were alarming: 43 out of 50 had Row Level Security (RLS) policies that provided zero actual protection.

The methodology

We selected 50 publicly deployed Lovable apps from showcase galleries, social media posts, and community forums. For each app, we extracted the Supabase project URL from the client-side JavaScript bundle and tested the RLS policies using the Supabase REST API with the anonymous key.

Our testing was straightforward: we attempted to read all rows from every table, insert arbitrary data, update existing rows, and delete records. We did this using only the anon key that was already exposed in the client-side code.

What we found

The breakdown was stark:

  • 43 apps (86%) had at least one table with a USING(true) policy, granting full read access to anonymous users
  • 31 apps (62%) had tables where anonymous users could insert data
  • 17 apps (34%) had tables where anonymous users could delete or update other users' data
  • Only 7 apps (14%) had properly scoped RLS policies tied to auth.uid()

Why this happens

The root cause is how AI code generators handle Supabase setup. When you ask an AI code generator to "add a database table for user profiles," the generated SQL typically looks like this:

CREATE TABLE profiles (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  user_id UUID REFERENCES auth.users(id),
  display_name TEXT,
  bio TEXT
);

ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Allow all access" ON profiles
  FOR ALL USING (true) WITH CHECK (true);

The AI enables RLS (good) but then creates a policy that allows everything (catastrophic). The developer sees "RLS: Enabled" in the Supabase dashboard and assumes they are protected.

The fix

Every USING(true) policy should be replaced with a policy scoped to the authenticated user:

-- Drop the dangerous policy
DROP POLICY "Allow all access" ON profiles;

-- Create proper read policy
CREATE POLICY "Users can read own profile" ON profiles
  FOR SELECT USING (auth.uid() = user_id);

-- Create proper write policy
CREATE POLICY "Users can update own profile" ON profiles
  FOR UPDATE USING (auth.uid() = user_id)
  WITH CHECK (auth.uid() = user_id);

If you need some data to be publicly readable (like a public profile page), create a separate select-only policy with narrow conditions instead of blanket access.

How to check your app

Run a free Sekrd scan on your app's URL. We will connect to your Supabase project, enumerate every table's RLS policies, and flag any USING(true) or WITH CHECK(true) policies as critical findings. You will get copy-paste SQL to fix each one.

Don't ship until you're sekrd

Run a free scan to find the vulnerabilities your AI missed.

Scan Your App Free