You shipped it in a weekend. Nobody checked it.
Your app works, people use it, and somewhere in it is a default nobody set. This page explains what vibe-coding tools ship out of the box, the five leaks we find in almost every AI-built app, and how to check yours tonight. Five minutes, no jargon.
Already worried? Skip to the free check
The tools optimise for working, not for safe
Lovable, Bolt and Cursor are brilliant at getting to “it works”. To get there fast they pick convenient defaults. None of them are bugs. All of them are open doors until someone closes them.
Your database key is in the page
Supabase and Firebase are built to be called straight from the browser. So the key sits in your JavaScript, on purpose. That is fine only if your database rules are right. Most vibe-coded apps never set those rules.
Every table answers, to everyone
Row Level Security is what tells a table who may read which rows. It is off until someone turns it on. With it off, the same key that loads your own profile also loads everyone else's.
Nothing is rate-limited
Your login, your signup, your AI endpoint: they answer as often as anyone asks. A script can try ten thousand passwords, or burn through your OpenAI credit, before you notice.
The code map is public
Build tools ship source maps by default. Attackers use them to read your original code, including the routes you thought were hidden and the checks you only do on the client.
The five leaks in almost every vibe-coded app
These are not theoretical. They are what turns up when founders send us an app that was built fast. For each one: why it happens, and what an attacker does with it.
Open database tables
Why it happens: Row Level Security off, or a policy that says 'anyone can read'.
What an attacker does: Opens your site, copies the key from the network tab, asks the database for the users table. Gets every row: names, emails, sometimes addresses and order history. Takes under a minute.
Secret keys in your JavaScript
Why it happens: An OpenAI, Stripe or service-role key pasted where a public key should be.
What an attacker does: Runs your AI on your bill, or with a service-role key skips every rule your database has. This is the one that turns a small leak into a total one.
Files that should not be public
Why it happens: A .env file, a .git folder or a database dump deployed along with the site.
What an attacker does: Requests yourdomain.com/.env and reads your secrets in plain text. Or downloads .git and rebuilds your entire codebase, history included.
Open APIs without limits
Why it happens: Routes that return data by id, with no login check and no rate limit.
What an attacker does: Counts up: /api/orders/1, /api/orders/2, /api/orders/3. Every customer's order, exported with a for loop.
Anyone can email as you
Why it happens: No SPF and DMARC records on your domain.
What an attacker does: Sends 'your invoice' or 'reset your password' from your exact address to your own customers. Your name, their trust, someone else's link.
All five are visible from the outside, without a login. That is why they are found first, and why they can be checked in seconds.
Your AI said it added security. Did it?
The most common fix attempt is also the least effective: ask the same tool to “make it secure”. It will add checks, say done, and mean it. But it adds them where it can see them, in the browser, and an attacker does not use your browser. The database is still open. The key is still public.
The tool that built the app cannot audit the app. Verification has to come from outside: a person or a scanner that behaves like an attacker, not like a builder.
What the research says
of AI-generated code contains security vulnerabilities, across every model and every tool tested. Not because the models are bad, but because “it runs” is the only thing they can verify.
Source and more numbers on Ainomiq Security.
One week, start to finish
A composite of the stories we hear. No single founder, every detail real.
- Saturday
You ship. The launch post does well. Fifty signups by evening.
- Sunday
Someone curious opens the network tab, sees a database key and tries it. Every table answers.
- Monday
A screenshot of your users table is on X. 'Built with Lovable, secured with nothing.'
- Tuesday
A user emails: 'Did you leak my data?' Under GDPR you have 72 hours to notify. You have no idea what was taken, because nothing was logged.
- Wednesday
You ask the AI to 'make it secure'. It adds checks in the browser, says done, and the database is still open.
Everything on this list is cheaper to check on Friday than to explain on Tuesday.
Five things you can check tonight
No tools, no signup, fifteen minutes. If you would rather not, the free check below does all of this and twenty more in 20 seconds.
- 1
Look for your key
Open your app, press F12, go to Network, reload. Find a request to supabase.co or firebaseio.com and note the key in the headers. That key is public. Now ask: what does it allow?
- 2
Ask a table for rows
In Supabase, open Table Editor and check the RLS badge on every table. Any table without it is readable with the key you just found. That is the users-table leak.
- 3
Request the files
Visit yourdomain.com/.env and yourdomain.com/.git/config. If anything but a 404 comes back, your secrets or your code are downloadable right now.
- 4
Count an API
Take any route that ends in an id and change the number. If you see someone else's data while logged out, so does everyone.
- 5
Check your domain's mail records
Search 'DMARC lookup', paste your domain. No DMARC record means anyone can send mail as you.
Found one?
Do not panic and do not ask the AI to fix it blind. Turn on RLS first, rotate any secret key second, then run the full check to see what else is open.
Straight answers
Is vibe coding itself the problem?
No. Lovable, Bolt, Cursor and v0 are the fastest way to get a real product in front of real people. The problem is that they optimise for working, not for safe, and the defaults they pick (public keys, open tables, no limits) are invisible unless you know to look. Keep vibecoding. Check before real users and real payments arrive.
Why can't I just ask the AI to secure it?
Because the model that made the mistake cannot see it. Ask Cursor to 'make it secure' and you get confident code that checks things in the browser, where an attacker simply skips it. Independent research keeps finding vulnerabilities in roughly 45% of AI-generated code. Verification has to come from outside the tool.
My app is small. Who would bother?
Nobody targets you. Scripts scan every new domain for the same five defaults, automatically, all day. Small apps get hit because they are easy, not because they are interesting.
What does the free check actually do?
It sends a few dozen small requests any visitor could make and reports only what it really observed: a table that returned rows, a key in your bundle, a file that answered. Nothing is written, nothing is brute-forced, no signup, no email. If your app is clean on the outside, it says so.
See your app the way an attacker sees it
Paste your domain. In 20 seconds you know which of the five doors is open: keys in your JavaScript, tables that answer without a login, files that should not be public, missing protection. Free, no signup, no email.