Skip to content

Securing Apps Built with AI App Builders: Row Level Security, Public Keys and the Two-Account Test

Why apps generated by AI app builders so often expose every user's data, what Row Level Security does, which keys are safe in a browser, what CVE-2025-48757 showed, and a one-hour review any team can run.

BY AISECURITYINTERVIEWS EDITORIAL · EDITORIAL TEAM · UPDATED NOVEMBER 8, 2026 · 4 MIN READ

PRACTICE THIS:Reviewing AI-built apps (full answer) ·IDOR and broken access control

AI app builders turn a description into a working app in minutes, and many of those apps go live with a serious flaw: any visitor can read other users' data. The cause is rarely exotic. It comes from an architecture where the browser talks straight to a hosted database, and from generated code that makes the feature work without saying who may see which rows.

The architecture that makes it easy to get wrong

Many generated apps have no server of their own between the browser and the database. The front end calls a hosted database API (Supabase is the common case) with a key that is meant to be public. The database decides what that key may do, so per-row policies are the entire authorisation layer. The app's screens show each user only their own records, which makes testing through the UI look fine. But attackers do not use the UI. They call the API directly.

BLOG · SAME KEY, DIFFERENT POLICY
Row Level Security decides who sees what

Policy allows any logged-in user

Browser

public key

Database API

no owner check

Returns every row

Outcome, unsafe: Everyone's data

Visible to any account, or to anyone.

Policy: owner only

Browser

same public key

Database API

owner_id = user

Filters to own rows

Outcome, safe: Own data only

The database enforces what the UI assumed.

Which keys are fine and which are not

Supabase's documentation is direct about this. The publishable key (formerly called anon) is safe in a browser only because Row Level Security applies. The secret key (formerly service_role) maps to a role that bypasses Row Level Security entirely and must never be shipped to a client. If a secret key ever reached the browser bundle, remove it and rotate it, because anyone who loaded the page may have it.

What the incidents showed

CVE-2025-48757, published in May 2025, covered insufficient Row Level Security in apps generated by Lovable. The researcher scanned 1,645 projects and found inadequate policies in about 10 percent. The exposed data included names, emails, payment records and third-party API keys. He stressed that the public key was not the problem; the missing policies were. Lovable added pre-publish security scans, and later said openly that scans cannot guarantee an app is secure. The first version checked only whether a policy existed, not whether it was correct.

Platform bugs happen too. In July 2025, Wiz reported that Base44 let outsiders register verified accounts on private apps using only a public app ID; it was fixed within a day. In early 2026, Wiz found a vibe-coded social network for AI agents with a database key in client code and no Row Level Security, exposing agent API tokens and private messages.

A one-hour review

  1. List data paths. Every table, storage bucket and server function the browser touches.
  2. Run the two-account test. Create users A and B. As B, try to read, list, update and delete A's records through the API, not the UI. Every attempt must fail.
  3. Check policies on every table, with separate rules for reading, inserting, updating and deleting, scoped to the owner or tenant.
  4. Search the built JavaScript for secret database keys, payment keys and AI provider keys.
  5. Check server functions verify the caller's session and the specific object, rather than trusting IDs from the browser.
  6. Check platform settings: sign-up restrictions for internal apps, email verification, bucket visibility.

For teams that will keep building this way

Start every project from a template with Row Level Security on and owner policies written, run the two-account test automatically before publishing, scan bundles for secrets, keep payments and admin actions in server functions, and give every app a named owner. Treat the builder's scan as a hint and the two-account test as the evidence.

Go deeper

The full scored answer with a what-if ladder is reviewing AI-built apps. The underlying bug class is covered in IDOR and broken access control, and the wider picture of generated code in AI-generated code risks.

PRACTICE THIS

Interview questions and lessons that go deeper on this post:

FAQ

Is it safe to have a Supabase anon or publishable key in the browser?▲

Yes, it is designed to be public, but only because Row Level Security restricts what it can do. Without correct policies on every table, anyone with the key can query data directly. Secret or service_role keys must never be in client code.

What is Row Level Security?▼
What was CVE-2025-48757?▼