<?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: Badii Boutar</title>
    <description>The latest articles on DEV Community by Badii Boutar (@badii_studio).</description>
    <link>https://dev.to/badii_studio</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%2F4203101%2Ffe352c41-ddf7-43a9-b396-7dc46fa81e9a.png</url>
      <title>DEV Community: Badii Boutar</title>
      <link>https://dev.to/badii_studio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/badii_studio"/>
    <language>en</language>
    <item>
      <title>Is my Supabase app leaking data between users?</title>
      <dc:creator>Badii Boutar</dc:creator>
      <pubDate>Fri, 23 Oct 2026 16:58:19 +0000</pubDate>
      <link>https://dev.to/badii_studio/is-my-supabase-app-leaking-data-between-users-5b27</link>
      <guid>https://dev.to/badii_studio/is-my-supabase-app-leaking-data-between-users-5b27</guid>
      <description>&lt;p&gt;It might be, and you can’t tell from the app’s UI. If row-level security is off or a policy is too open, anyone with your public anon key can query the table directly, and the Launch Audit checks every table for this.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Of 1,072 vibe-coded apps scanned, 172 let anyone delete records from the database without logging in.&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://www.symbioticsec.ai/blog/we-scanned-1-072-vibe-coded-apps-98-had-security-flaws" rel="noopener noreferrer"&gt;Symbiotic Security&lt;/a&gt;, 2 Jun 2026&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why this happens
&lt;/h2&gt;

&lt;p&gt;In apps built with Lovable, Bolt and similar tools, the browser talks to Supabase directly with the anon key. That key is public by design. Row-level security (RLS) policies are the only thing deciding which rows each request can read or change.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I check
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;RLS is turned on for every table in exposed schemas.&lt;/li&gt;
&lt;li&gt;Policies compare rows to auth.uid(), not to a value the client sends.&lt;/li&gt;
&lt;li&gt;Insert and update policies stop users from setting someone else’s user_id or their own role.&lt;/li&gt;
&lt;li&gt;Storage buckets have policies too, and private files are not public.&lt;/li&gt;
&lt;li&gt;Views and functions do not bypass RLS by running as the owner.&lt;/li&gt;
&lt;li&gt;I test it: two test accounts, one tries to read and change the other’s data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A quick check you can do now
&lt;/h2&gt;

&lt;p&gt;In the Supabase dashboard, open Database, then Tables. Any table marked as having RLS disabled can be read by anyone with your anon key. Supabase’s Security Advisor also lists them. Turning RLS on without policies blocks all access, so add policies before you switch it on in production.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;First published on &lt;a href="https://badii.studio/supabase-rls-audit" rel="noopener noreferrer"&gt;badii.studio&lt;/a&gt;. I review and fix apps built with Lovable, Bolt and other AI tools before launch.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>supabase</category>
      <category>security</category>
      <category>postgres</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
