Vibe coding security

Is your vibe-coded app leaking?

The AI wrote the feature. It did not check what it exposed. This is the short list of what an outsider can read from a vibe-coded app, and how to see it before they do.

Vibe coding securityis the practice of finding and closing the holes an AI coding assistant leaves behind. When you build fast by prompting a model, the app works before anyone checks what it hands to the public: a secret key in the browser, a database table with no access rule, an API that returns everyone's data. None of it looks broken. All of it is readable from outside.

The usual way it goes: you ship a table with row-level security still off, because the tutorial said that was fine for a demo. Your app reads it from the browser with the public key. So can everyone else. A stranger opens the network tab, sees the request your own page makes, and repeats it - and every row comes back. No login, no exploit, no skill. Just the same request your homepage already sends.

The exposures to check, worst first

Vibe coding security: what your AI-built app hands the public

The model optimized for making it work, not for keeping it quiet. The exposures AI-built apps ship by default, why they happen, and how to check yours from outside.

Supabase security: what a stranger can reach with your public key

The anon key is public by design; your row-level security is the gate. What a stranger can reach with that public key, and how to check which side of the line your project is on.

Did you leak a Supabase service_role key? (It bypasses every security rule you wrote)

The Supabase service_role key skips row-level security entirely. If it shipped to the browser, your RLS policies protect nothing. How to check and fix.

Your Supabase table has no row-level security, so your anon key reads all of it

A Supabase table with no row-level security is readable by anyone holding the public anon key, which is everyone. How the gap opens in a vibe-coded app, and how to check.

Your front-end is calling an API that hands back everyone's data, not just the logged-in user's

The page loads, fires a quiet fetch, and the response carries hundreds of people's names, emails, and roles. Broken object-level authorization is the most common API flaw there is, and it's readable from the browser. How the leak looks, and how to check.

Your live site's login is wired to Clerk's development instance

A Clerk pk_test_ publishable key is public by design, but on a production domain it means your live auth runs on the shared development instance: weaker limits, test OAuth, *.accounts.dev. How to spot it from outside, and the fix.

Can anyone download your .env file? (Type the URL and find out)

A public .env hands a stranger your database password, API keys, and secrets in one request. How it leaks, how to check, and how to shut it.

Does "vibe coding" leave security holes? (Yes, here's where)

The AI wrote the feature. It did not check what it exposed. The specific holes vibe-coded apps ship, and how to find them from outside.

Vibe coding best practices: shipping fast without shipping holes

The habits that keep an AI-built app fast to ship and safe to launch. Where each key lives, the gate on every table, and the one check to run before you go live.

Common questions

Is my vibe-coded app safe?
Not automatically. In a controlled 2025 study, Veracode found AI introduced a known security flaw in 45% of the code-generation tasks it tested when the model was given no explicit security guidance. That does not mean half of all shipped apps are broken, but it does mean the code an assistant writes is not secure by default. The holes that show up from outside are usually a small set: a key that shipped to the browser, a database table with no access rule, and an API that returns more than it should. Those are the ones worth checking first.
Why is there an API key in my frontend, and is that a problem?
Some keys belong in the browser and some do not. A publishable key, like a Supabase anon key or a Stripe publishable key, is public by design and shipping it is fine. A secret key, like a Supabase service_role key or a Stripe secret key, is a fire: the Supabase service_role key bypasses row-level security entirely and gives whoever holds it full read, write, and delete on every table. The rule is simple: publishable keys can ship, secret keys never can. If you cannot tell which one you have, that uncertainty is the thing to resolve first.
How can my waitlist or user data be visible in the frontend?
Because the browser queries your database directly and the only thing stopping it is a policy you may not have written. With Supabase, the public anon key can read any table that has no row-level security rule. Supabase enables RLS by default on tables made through its dashboard, but tables created in raw SQL or a migration, which is the path an AI assistant takes, do not get it automatically. So the waitlist table ships, the query runs from the browser, and every row comes back to anyone who sends the request. The fix is a policy on the table, not hiding the key.
Does the same thing happen with Firebase?
Yes, through Firebase Security Rules. Firebase lets the client read and write the database directly, and the rules are the only safeguard. When you create a database you choose Locked mode (deny by default) or Test mode (allow anyone). Ship an app that is still in Test mode and, in Firebase's own words, anyone who guesses your project ID can steal, modify, or delete the data. The classic open ruleset, allow read and write if true, carries Firebase's warning to never use it in production.
How do I check what my AI-built app is exposing?
Open your live site in an incognito window with no login, open the browser's network tab, and watch what the page requests. Every call to your backend or database is something a stranger can make too. For each response that carries data, ask whether a logged-out visitor should see it. A passive external scan does the same thing at scale: it reads what your site already serves to the public and grades it, without sending an attack or logging in. That is what SurfaceCheckr does, and it is why the exposures on this page are exactly the ones it looks for.

Scan it. See the exposures these guides describe.

Paste your domain. The grade and issue count are free, and you'll see in a couple of minutes exactly what a vibe-coded app is handing the public.

External, read-only scan. We only request public URLs - never log in, never send attack traffic.