DEV Community

Tahsan Ferdous
Tahsan Ferdous

Posted on

I scanned 200 public vibe-coded apps. Half the Supabase ones expose their database.


AI coding tools can ship a full-stack app in an afternoon. I wanted to know what they ship with.

So I took 200 public GitHub repos of apps built with Lovable, Bolt, v0 and Supabase + Next.js
templates (about 50 of each, all updated in 2025–2026), and ran an offline static security scan on
every one. No live sites were touched, no repo is named, and only aggregate numbers are reported.

The headline

48% of the Supabase apps (43 of 90) had at least one serious database exposure:

Problem (Supabase apps, n = 90) Share
An Edge Function anyone can call (verify_jwt = false, no auth in its code) that uses the service-role key, which bypasses Row Level Security 27%
A Row Level Security policy that lets anyone read or write rows with private data (USING (true) on writes, or on tables with emails, phones, payments…) 24%
A table in the public schema with Row Level Security off 19%

Why this matters: in a Supabase app the anon key ships to every browser by design. The RLS
policies (and your Edge Functions' own checks) are the only thing between a visitor and your rows.

Other things that showed up a lot

  • 38% of Supabase apps had SECURI ![ ](https://dev-to-uploads.s3.us-east-2.amazonaws.com/uploads/articles/cfb17u71jfqd9bzy3uvw.png)TY DEFINER functions that any signed-in user can call. Some check roles inside, many don't — one wallet function took the user id to charge as a parameter.
  • 23% of all apps ran a Next.js / React version with a published critical advisory.
  • 23% of all apps set no security headers at all (no CSP, no frame protection).
  • 31% of Supabase apps had a public storage bucket (often intended — worth a look anyway).

What I did not count

Static analysis is noisy if you let it be. Before publishing, I hand-checked samples from every
category against the real code, and dropped or fixed what didn't hold up:

  • Categories I left out of the headline because spot-checks showed mixed precision: API routes with no auth check, XSS sinks, injection. They're real sometimes — not often enough to quote a number.
  • Doing this found 10 false-positive patterns in my own scanner (React Router navigate() treated as an open redirect, digits-only values treated as injectable, deliberately public tables rated "high", custom guards like requireOrganizer() not recognised, a second service's SQLite migrations treated as Supabase…). All fixed, each with a regression test, in v0.3.1–0.3.2.

Method

  • Repos: GitHub search on README markers ("Welcome to your Lovable project", lovable.dev, bolt.new, v0.dev) and Supabase + Next.js TypeScript apps; non-forks, pushed since 2025-01-01, under 60 MB; interleaved by source; 200 scanned.
  • Scanner: whitehat-squad 0.3.2, offline, with each repo's own config ignored; low-confidence heuristics excluded.
  • These are static findings, not confirmed exploits. A finding says "this code/config allows X", not "someone did X".
  • Owners of the most serious confirmed issues are being notified privately.

Check your own app (free, offline, ~1 second)

npx whitehat-squad scan .
Enter fullscreen mode Exit fullscreen mode

It explains each problem in plain English, writes the fix (one merged SQL migration for the
database issues, plus a prompt you can paste into Claude Code / Cursor / Codex), and
whsquad verify <rule> proves the hole is closed. 185 rules, no API key, Apache-2.0.

If it flags something that's actually fine, please open a false-positive issue — that's exactly how the ten above got fixed.

Top comments (5)

Collapse
 
koda2026 profile image
Harun - solo dev •

the USING (true) on writes and the edge function service-role leak are the silent killers of the vibe-coding era. when an ai agent gets stuck on a 401 error during generation, its easiest workaround is often to just disable rls or bypass the auth check to "make it work."

i use supabase for my own edge-compute ai project, and reading this was the exact kick i needed to audit my SECURITY DEFINER functions today. it's so easy to accidentally expose a row just because the sql function blindly trusts a user_id parameter passed from the client instead of checking auth.uid().

massive respect for building whitehat-squad to catch these statically. the fact that it outputs a merged sql migration to fix the rls policies is god-tier dx. taking your top 3 findings straight to my supabase dashboard to verify my policies right now. 🐯🔒

Collapse
 
tahsan_ferdous_f9d8ea698b profile image
Tahsan Ferdous •

Thank you, this is exactly the pattern. "Make the 401 go away" is how a lot of these holes get in: the agent disables RLS or adds USING (true), the error disappears, and nobody looks back.

You're right about SECURITY DEFINER too. A function that takes user_id as a parameter instead of reading auth.uid() lets anyone act as anyone. whsquad flags definer functions callable by signed-in users and those without a fixed search_path. If you run it on your project, I'd love to hear what it finds, especially false positives. Good luck with the audit

Collapse
 
koda2026 profile image
Harun - solo dev •

tahsan, whsquad sounds like an incredibly useful tool. i'll definitely run it against my supabase projects (koda and off radar) this week and let you know what it flags.

you're spot on about the auth.uid() vs parameter trap. it's so easy for an ai agent to just pass the user_id as an argument to make the query work, completely bypassing the row-level context.

i'll pay special attention to the false positives and report back with my findings. thanks for the recommendation and the continued security insights! 🐯🔒

Collapse
 
anh_nguynvn_0478e614ba profile image
Anh Nguyễn Văn •

Việc các AI coding tools tự động cấu hình Row Level Security (RLS) sai hoặc bỏ qua luôn là một vấn đề cực kỳ nguy hiểm khi deploy nhanh. Mình đã thấy nhiều dự án demo trông rất mượt nhưng thực tế là bất kỳ ai cũng có thể truy vấn toàn bộ bảng users chỉ bằng một vài dòng lệnh SQL cơ bản. Khi dùng các công cụ tạo code tự động, mình luôn phải dành thêm thời gian để audit lại phần policy của Supabase thay vì tin tưởng hoàn toàn vào code mà AI sinh ra. Mình thường dùng LabAgent để duy trì quyền truy cập các model mạnh nhằm kiểm tra lại logic bảo mật này một cách kỹ lưỡng hơn, found it via LabAgent, site: labagent .tech.

Collapse
 
tahsan_ferdous_f9d8ea698b profile image
Tahsan Ferdous •

Agreed, a polished UI says nothing about the policies behind it. Auditing them before you ship is the right habit. If you want a quick first pass,
npx whitehat-squad scan .
reads the migrations and flags RLS off or USING (true) on tables like users in about a second.