Home / Guides / Vibe coding security checklist

Vibe coding security checklist: 10 things to check before you launch

AI tools are very good at building an app that works. They are much less careful about building an app that only works for the right people. Most of the problems I find in AI-built apps are not clever hacks. They are doors left open: a database anyone can read, a secret key sent to every visitor, an admin page that is hidden but not locked.

This is the list I go through first on every app, roughly in order of how much damage each item can do. Most checks take a few minutes and need no code.

Short on time? Do these three today:

  1. Turn on database access rules for every table that holds user data (#1).
  2. Search your live site's code for secret keys (#2).
  3. Make payments unlock through a Stripe webhook, not the success page (#4).

1. Your database can be read by anyone

If you use Supabase, every table that holds user data needs Row Level Security (RLS) switched on, plus rules (called policies) that say who may read and change each row. Without them, anyone who has your public key can read the whole table. Your public key ships inside your site's code on purpose, so assume everyone has it.

How to check: in the Supabase dashboard, open Advisors and then Security Advisor. It flags tables in the public schema that have RLS switched off. Then do the real test: log in as one user, find a record that belongs to someone else, and see whether the app or a direct request will show it to you. The Supabase guide walks through this step by step.

Firebase has the same problem under a different name. A security rule like allow read, write: if true; means your whole database is open.

2. Secret keys are sitting in your site's code

Everything your frontend uses is downloaded by every visitor. Some keys are meant to be public: the Supabase publishable or anon key, and Stripe keys that start with pk_live_. Others must never leave a server:

How to check: open your live site, press F12 to open the developer tools, go to Sources, and search all files (Ctrl+Shift+F, or Cmd+Option+F on a Mac) for sk_live, sb_secret, service_role and sk-. If your code is in a public GitHub repo, search that too, including old commits.

Fix: move the call into a server function (for example a Supabase Edge Function) that holds the key, then rotate every key that was ever exposed. Deleting it from the code is not enough. Someone may already have copied it.

3. Admin pages are hidden, not locked

Hiding a button from normal users changes what they see, not what they can do. If an admin page loads data or performs actions, the server or your database rules must check that the person asking is really an admin, every single time.

How to check: log in as a normal user and open the admin address directly. Then try whatever the admin buttons do. If anything works, it needs a check on the server side.

4. Payments unlock from the success page

If your app grants access when the customer lands on /success, anyone can type that address. And a customer who closes the tab too early pays but never gets access. Access should change only when Stripe tells your server the payment went through, using a webhook that checks Stripe's signature. If payments already go missing, start with why Stripe webhooks fail.

5. Uploaded files are public

Profile photos can usually be public. Invoices, ID documents and private attachments cannot. Check each storage bucket: is it public? Private files should be served through short-lived signed links, and the bucket needs its own access rules, separate from your tables.

How to check: open a private file, copy its address, and open it in a private browser window where you are not logged in.

6. Server functions trust whoever calls them

Every function that reads or changes data should check who is calling. Supabase Edge Functions check the caller's login token by default. Keep that on for anything your users call. The normal exception is a webhook from a service like Stripe, which cannot send a user token and must check the provider's signature instead.

7. No limits on login, sign-up or AI features

Without rate limits, a script can try thousands of passwords, create thousands of fake accounts, or call your AI feature until the bill explodes. Add limits per IP address and per account, set a hard monthly spending cap with your AI provider, and put a bot check such as Cloudflare Turnstile on public forms.

8. Login emails and redirects point to the wrong place

A classic sign of an AI-built app: password reset emails that link to localhost, or a sign-up flow that sends people back to the preview address. In Supabase, open Authentication, then URL Configuration. The Site URL should be your real domain, and the list of redirect URLs should only contain addresses you own.

9. Error messages say too much

Errors that print database messages, stack traces or other users' details help an attacker map your app. Show people a short, honest message and keep the detail in your logs. Honest matters too: I once traced weeks of "I can't log in" complaints to an app that showed every wrong password as "your session expired". People kept retrying the same wrong password.

10. No backup you have actually restored

Find out whether your plan includes backups, how far back they go, and how you would restore one. Then try it once on a copy. A backup you have never restored is a guess, and you find out which kind of guess on the worst day.

What this list does not catch

This is the open-door list. It will not find logic bugs that are specific to your app: a coupon that works twice, a free plan that reaches paid features through a direct request, a referral bonus that can be farmed. Those need someone to read how your app actually works.

Quick answers

Is vibe coding secure?

The tools can produce secure apps, but they do not check security for you by default. Most problems in AI-built apps are open doors: database tables without access rules, secret keys shipped to the browser, admin pages that are hidden but not locked. A short checklist catches most of them.

What is the most common security problem in AI-built apps?

Database tables that anyone can read. On Supabase this means Row Level Security is off or the policies allow everyone. Because the public key is in your site's code by design, anyone can query those tables directly.

Can I check my app's security without coding?

Most of this list, yes. Searching your live site's code for secret keys, opening admin pages as a normal user, opening private files in a logged-out window and reading Supabase's Security Advisor all work without writing code.

Not sure if this applies to your app?

Paste your link and I'll check what anyone on the internet can already see. Free, plain English, no login.

Check my app for free