<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tahsan Ferdous</title>
    <description>The latest articles on DEV Community by Tahsan Ferdous (@tahsan_ferdous_f9d8ea698b).</description>
    <link>https://dev.to/tahsan_ferdous_f9d8ea698b</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4166927%2Fb0ab8e51-f24e-4aef-aca6-5440cdb52243.png</url>
      <title>DEV Community: Tahsan Ferdous</title>
      <link>https://dev.to/tahsan_ferdous_f9d8ea698b</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tahsan_ferdous_f9d8ea698b"/>
    <language>en</language>
    <item>
      <title>I scanned 200 public vibe-coded apps. Half the Supabase ones expose their database.</title>
      <dc:creator>Tahsan Ferdous</dc:creator>
      <pubDate>Tue, 06 Oct 2026 16:38:16 +0000</pubDate>
      <link>https://dev.to/tahsan_ferdous_f9d8ea698b/i-scanned-200-public-vibe-coded-apps-half-the-supabase-ones-expose-their-database-tags-security-4e1j</link>
      <guid>https://dev.to/tahsan_ferdous_f9d8ea698b/i-scanned-200-public-vibe-coded-apps-half-the-supabase-ones-expose-their-database-tags-security-4e1j</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp615ni21hoj6ep5eopmo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp615ni21hoj6ep5eopmo.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;
AI coding tools can ship a full-stack app in an afternoon. I wanted to know what they ship &lt;em&gt;with&lt;/em&gt;.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  The headline
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;48% of the Supabase apps (43 of 90) had at least one serious database exposure:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem (Supabase apps, n = 90)&lt;/th&gt;
&lt;th&gt;Share&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;An Edge Function anyone can call (&lt;code&gt;verify_jwt = false&lt;/code&gt;, no auth in its code) &lt;strong&gt;that uses the service-role key&lt;/strong&gt;, which bypasses Row Level Security&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;27%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A Row Level Security policy that lets anyone read or write rows with private data (&lt;code&gt;USING (true)&lt;/code&gt; on writes, or on tables with emails, phones, payments…)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;24%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A table in the public schema with &lt;strong&gt;Row Level Security off&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;19%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;h2&gt;
  
  
  Other things that showed up a lot
&lt;/h2&gt;

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

&lt;h2&gt;
  
  
  What I did &lt;em&gt;not&lt;/em&gt; count
&lt;/h2&gt;

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

&lt;ul&gt;
&lt;li&gt;Categories I &lt;strong&gt;left out of the headline&lt;/strong&gt; 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.&lt;/li&gt;
&lt;li&gt;Doing this found &lt;strong&gt;10 false-positive patterns in my own scanner&lt;/strong&gt; (React Router &lt;code&gt;navigate()&lt;/code&gt; treated
as an open redirect, digits-only values treated as injectable, deliberately public tables rated
"high", custom guards like &lt;code&gt;requireOrganizer()&lt;/code&gt; 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.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Method
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;Scanner: &lt;a href="https://github.com/LihanCanCode/whitehat-squad" rel="noopener noreferrer"&gt;whitehat-squad&lt;/a&gt; 0.3.2, offline, with each
repo's own config ignored; low-confidence heuristics excluded.&lt;/li&gt;
&lt;li&gt;These are &lt;strong&gt;static findings&lt;/strong&gt;, not confirmed exploits. A finding says "this code/config allows X",
not "someone did X".&lt;/li&gt;
&lt;li&gt;Owners of the most serious confirmed issues are being notified privately.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Check your own app (free, offline, ~1 second)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx whitehat-squad scan &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;If it flags something that's actually fine, please &lt;a href="https://github.com/LihanCanCode/whitehat-squad/issues/new/choose" rel="noopener noreferrer"&gt;open a false-positive issue&lt;/a&gt; — that's exactly how the ten above got fixed.&lt;/p&gt;

</description>
      <category>database</category>
      <category>security</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
