Your vibe-coded app is probably leaking data, here's how to check.

The five most common ways AI-built apps (Lovable, Bolt, Cursor, v0) leak user data, and how to check each one yourself in about 20 minutes.

Your vibe-coded app is probably leaking data, here's how to check.
Photo by Towfiqu barbhuiya / Unsplash

If you built your app with Lovable, Bolt, Cursor or v0 and you've never looked at security, there's a real chance it's exposing your users' data right now and you'd have no idea. It's not that you did anything wrong. AI builders optimise for "it works," not "it's safe," and the safe part is the boring stuff they skip. The good news is that the most common leaks are easy to check yourself, and most are fixable in an afternoon. Here are the five I'd look at first, in order.

1. Secrets that shouldn't be public

Your app has secret keys. Database keys, Stripe secret keys, keys for any AI API you call. If any got committed to a public GitHub repo or baked into the code that runs in the browser, anyone can read and use them (think surprise $50k cloud bills, or someone draining your OpenAI credits).

How to check: open your repo on GitHub and look for a .env file or keys pasted directly in the code. Then on your live site, right-click, choose Inspect, open the Network tab, reload, and scan the requests for anything secret-looking (long strings starting with sk_, service_role, and the like). Anon/publishable keys (often VITE_ or NEXT_PUBLIC_) are meant to be public and are fine. Secret and service-role keys are not.

How to fix: rotate (regenerate) anything that was exposed, and assume the old one is burned. Move secrets into your host's environment settings, never a file in the repo or the frontend.

2. Your database has no lock on the front door (RLS)

The big one almost nobody checks. If you're on Supabase (most of these apps are), your "anon key" is public by design, it's supposed to be in the browser. The thing that stops a stranger from reading or deleting your whole database with that key is Row Level Security. AI builders very often leave it off.

How to check: in your Supabase dashboard, open the Table Editor. For each table, is RLS enabled, and does it have real policies? "RLS disabled" on a table with user data means anyone with your public key can read every row.

How to fix: turn RLS on for every table and add policies so users only see their own rows (e.g. user_id = auth.uid()). This is the difference between "secure" and "someone dumped my whole users table."

woman in black top using Surface laptop
Photo by Christina @ wocintechchat.com M / Unsplash

3. Can one user see another user's stuff?

Even with logins working, AI-built apps often forget to check ownership, so user A can see user B's data just by changing a number in the URL.

How to check: log in as one test user, open something private (an order, a doc, a profile), and note the ID in the URL or request. Then log in as a second user and try to open that first ID. If it loads, that's a leak.

How to fix: every request that returns private data needs a server-side check that the logged-in user actually owns it. Never trust the frontend to hide it.

4. Public file storage

If users upload anything (photos, IDs, invoices), those files often land in a bucket set to "public," meaning anyone with the link, or who can guess one, can open them.

How to check: in Supabase Storage (or wherever files live), see if the bucket is public or private. Grab a file's URL and open it in an incognito window where you're not logged in. If it loads, it's public.

How to fix: make the bucket private and serve files through signed, expiring URLs.

5. You're sending more data than the screen shows

Just because the page only displays a name doesn't mean the app only sent a name. AI-built apps often fetch the entire database row (emails, phone numbers, internal flags, sometimes password hashes) and just don't display the rest. It's all sitting in the browser's network tab for anyone to read.

How to check: open the Network tab again, click through your app, and read what the API responses actually contain. Fields your UI never shows mean you're over-sending.

How to fix: only select and return the columns you actually need, and make sure error messages don't leak internal details.

black laptop computer turned on on table
Photo by James Harrison / Unsplash

None of this means vibe coding is bad or that you shouldn't have used an AI builder. They're great for getting an idea live fast. It just means "make it safe for real users" is a separate job the AI didn't do. Go through these five: if everything's clean, you're ahead of most. If a couple made you wince, they're all fixable, and a lot cheaper to fix now than after the data's already out.


This is the kind of cleanup I do for AI-built apps. If you want a second set of eyes, I'll do a quick free teardown and tell you straight what's safe and what needs fixing. Book a call: calendly.com/raulgracia.