Last week I looked at a vibe coded app that had been running with real paying users for three months. The founder built it in an afternoon with Lovable. It worked beautifully in the demo. Fifty people had signed up, handed over their email addresses, and in some cases their payment details. Every single user's data was visible to every other user.
He had no idea. The AI tools he used didn't warn him. And I've seen this exact same issue (not a variation of it, the exact same thing) in the last six apps I reviewed.
Here are the five things I find in almost every vibe coded app, and what to do about each. None of these take more than an afternoon to fix once you know they exist. The cost of finding out the hard way is days of cleanup at minimum, and your reputation at worst.
01No row level security
The most common security issue in vibe coded apps. Your AI tool sets up a database, your users sign up, and from that moment on, every user can read every other user's data. The query select * from messages returns everyone's messages, not just yours.
What's missing is a thing called row level security (RLS): a policy at the database level that says “user X can only see rows where the user_id column equals their own ID.” Without this, the only thing standing between users and each other's data is the front end code, which anyone can bypass with two minutes of curl.
Writing one RLS policy per table takes about 20 minutes for an app with 5 to 10 tables. It is not negotiable before you have real users.
02API keys hardcoded in the client
Your AI tool needs to call OpenAI, or Stripe, or some other service. To make it work, it dropped the API key directly into your front end code. Anyone who opens DevTools on your app can see it. Anyone who finds it can use it. On your account.
I have personally found Stripe live keys, OpenAI keys with thousands of dollars of monthly usage, and admin level Supabase service keys sitting in publicly visible JavaScript files. The fix is a five line backend endpoint that makes the call on the user's behalf and never exposes the key.
Move the key to your server side code (env variables) and create a small API route that proxies the request. Vercel, Netlify, and Supabase all support this in their free tiers.
03Auth checked only on the client
Your AI built a login screen. The user can't see the dashboard until they log in. Looks secure, right? It's not. The check is happening in JavaScript, in the browser, where any user can disable it. Anyone with browser DevTools can flip a flag and see the dashboard without logging in.
Real authentication has to happen on the server, on every request. Each API call needs to verify the user's session token before returning anything. The front end check is a UX nicety, not a security boundary.
04No environment separation
Your dev environment, your staging environment, and your production environment are all the same database. When you click “test”, you're writing to your live users' data. When you reset your local data, you reset everyone's.
This sounds dramatic, but I see it constantly. The AI tool gives you one Supabase project, you start building, you start getting users, and you never set up separation. Three months later you accidentally drop a table and your live app goes down for a day.
Create separate projects for development, staging, and production. Use environment variables to switch between them. This is 30 minutes of work and saves you from a category of accidents that ruin weeks.
05Errors that leak internals
Your app has a bug, the API returns an error, and the error message says: “PostgreSQL error: could not connect to host 192.168.4.3 with user 'admin' on port 5432”. You just leaked your database internals to whoever triggered the bug. A motivated attacker now has a starting point.
AI tools default to verbose, helpful error messages: great for debugging, terrible for production. The fix is wrapping every API endpoint in a generic error response that logs the real error server side and returns a generic message to the user.
→If you've shipped a vibe coded app
And you have real users on it: spend an afternoon checking these five things. Most of them are 20 to 30 minutes to fix once you know they exist. The cost of finding out the hard way (through a data breach, a leaked Stripe key, your database getting wiped) is days of cleanup at minimum and your reputation at worst.
If you'd rather have us check, that's what we do. The audit is automated, takes three minutes, and tells you exactly which of these you have. We fix what's broken or rebuild what can't be fixed.