How this ranking was built
Two things put a risk near the top: how easily an app ends up with it, and how much damage follows when it does. A mistake that is common and also exposes the whole database beats a rarer one with a narrow impact.
The order below is a judgment call. There are no reliable public statistics on how often each failure occurs across small apps, and I am not going to invent any. If you fix the first three, you have covered the failures that most often turn a working demo into a data exposure.
1. Open database rules
Many AI-built apps let the browser talk directly to the database. That is fine when the database enforces who can read and write each row. It is a disaster when the rules are missing. In Supabase, the documentation says a table in an exposed schema without Row Level Security is readable and writable by any role with a grant on it.
This is the failure behind CVE-2025-48757, a vulnerability class reported in 2025 about missing Row Level Security in Lovable-generated Supabase projects. A researcher's public scan reportedly flagged 170 of 1,645 showcased projects, as relayed in secondary coverage. Treat those figures as reported, not verified by me. The mechanism is what counts: the app works for you, so the missing rule is invisible.
2. Secrets in the browser
Anything sent to the browser can be read by anyone who opens developer tools. Frameworks make this easy to get wrong. In Next.js, any variable prefixed with NEXT_PUBLIC_ is inlined into the JavaScript bundle at build time. If a payment secret key, a model provider key or a database service key carries that prefix, it is public.
Some keys are designed to be public, such as a Stripe publishable key or a Supabase anon key. The difference is what the key can do. A public key that relies on server-side rules is fine. A secret key that is itself the authority is not.
4. Public storage
File storage is a quieter twin of the open database. Buckets created as public serve every file to anyone who has the address. That is right for logos and wrong for invoices, ID scans or medical documents.
The mistake usually happens because a public bucket makes image previews work with no extra setup. The tool picks the setting that removes friction, and the sensitive files inherit it.
5. Unreviewed dependencies
AI tools install packages to solve problems, sometimes ones you would not recognize. Each package is code from a stranger running inside your app. Risks include abandoned libraries with known flaws and, more rarely, look-alike names of popular packages. It ranks lower than the first four because it usually needs more luck to hurt you, but it accumulates over time.
6. Debug leftovers
Test accounts with weak passwords, verbose error pages that reveal internals, admin routes added for convenience and console logs that print tokens all tend to survive into production. They are individually small. Combined with any other weakness, they hand an attacker a map.
Risk, symptom, test and fix at a glance
Only test systems you own. Each test below is something you can do to your own app without special tools.
| Risk | How it appears | How to test your own app | Fix |
|---|---|---|---|
| Open database rules | Tables readable or writable with the public key | Query a table with the public key while logged out and see if rows return | Enable Row Level Security on every table and write narrow policies |
| Secrets in the browser | Secret keys visible in downloaded JavaScript | Search your deployed app's JavaScript files for key prefixes such as sk_ and service_role | Move the call to a server route, revoke and rotate the exposed key |
| Missing server-side authorization | Users can fetch or edit other users' records by changing an ID | Sign in as user B and request user A's record by its ID | Check ownership on the server for every read and write, deny by default |
| Public storage | Private files open to anyone with the URL | Open a private file's URL in a logged-out window | Make the bucket private, serve files through short-lived signed URLs |
| Unreviewed dependencies | Unknown or unmaintained packages in the manifest | Run your package manager's audit command and read the package list | Remove what you do not need, update, pin versions, review new additions |
| Debug leftovers | Test accounts, verbose errors, hidden admin routes | Search the code and settings for test, admin and debug; trigger an error on purpose | Delete test accounts and routes, turn off verbose errors in production |
Where to start if you have one hour
- 1List every table and confirm Row Level Security is on for each one that is exposed to the browser.
- 2Search the built JavaScript and the repository for secret key patterns, and rotate any you find.
- 3Sign in as two different users and try to read each other's data through the app and through direct requests.
- 4Check that every storage bucket holding user files is private.
- 5Run a dependency audit and remove packages you do not recognize.
- 6Delete test accounts and confirm production error pages reveal nothing.
Frequently asked questions
What is the biggest security risk in vibe coding?
In my judgment it is missing access rules on the database, because it exposes data directly and stays invisible while you test as the owner. Secrets in browser code and missing server-side authorization come close behind. These three explain most avoidable exposures in small apps.
Are AI coding tools like Cursor or Lovable secure by default?
Not reliably. They optimize for working features, and secure behavior depends on your prompts, settings and review. Some platforms add helpful warnings, but you should verify access rules, secrets and storage settings yourself rather than assuming a default is safe.
How do I check if my vibe coded app has been exposed?
Check your provider's logs for unfamiliar requests, look for unexpected usage on paid API keys, and test your own tables and files while logged out. If a secret key was ever in browser code, rotate it regardless of whether you see misuse.