Back to blog

Vibe Coding Security Checklist: 12 Checks Before You Launch an AI-Built App

The security mistakes AI coding tools make most often, from leaked API keys to Supabase tables without Row Level Security, and a 12-point checklist to run before launch.

Oct 19, 2026SiteXraySiteXray
Vibe Coding Security Checklist: 12 Checks Before You Launch an AI-Built App

AI coding tools are very good at making an app work. They are much less careful about who else can make it work. Public scans of apps built with Lovable, Bolt and similar tools keep finding the same handful of problems, and nearly all of them are visible from outside the app, without any login.

The three mistakes that show up most

1. Databases without Row Level Security. Supabase and Firebase hand your front-end a public key on purpose. That is safe only if every table has rules saying who can read and write which rows. A researcher's scan of 1,645 live Lovable projects found more than 170 with Row Level Security misconfigured (tracked as CVE-2025-48757). With RLS off, the public key reads the whole table.

2. Secret keys shipped to the browser. When a tool wires up Stripe, OpenAI or a Supabase admin call, the quickest working version often puts the secret key in client code. Anything in a JavaScript bundle is public. One scan of Bolt-hosted apps found hardcoded keys in about 7% of them.

3. Missing basics on the server. No security headers, open .env or .git directories on self-hosted deploys, verbose error pages, and endpoints that trust whatever user ID the browser sends.

The checklist

Run through these before you share the link.

Keys and secrets

  1. Search the built output (not just your source) for sk_live_, sk-, service_role, sb_secret_, AKIA and -----BEGIN. The free scanner does this for your homepage and its scripts.
  2. Only publishable keys in the front-end: Stripe pk_, Supabase anon / publishable key, Firebase web config. Everything else goes in server environment variables.
  3. If a secret was ever in client code or a public repo, rotate it. Deleting it from the code does not un-leak it.

Database rules

  1. Supabase: enable RLS on every table and write policies, then run Security Advisor in the dashboard. Firebase: no allow read, write: if true in Firestore or Storage rules.
  2. Test as a stranger: open the app in a private window, call your API or the Supabase REST endpoint with only the anon key, and try to read another user's rows.

Server-side checks

  1. Every API route checks the session on the server. Never trust a userId, role or price sent from the browser.
  2. Rate-limit login, signup, password reset and any endpoint that spends money (AI calls, emails, SMS).
  3. Validate uploads by type and size, and store them outside the web root or in object storage.

Deployment

  1. HTTPS everywhere with HTTP redirecting to it, plus HSTS.
  2. Security headers: Content-Security-Policy, frame-ancestors, X-Content-Type-Options: nosniff, Referrer-Policy.
  3. No .env, .git, source maps or debug pages reachable from the internet.
  4. Runtimes on supported versions: Node.js 22, 24 or 26 with the October 2026 security release, or PHP 8.2.35+ / 8.3.36+ / 8.4.27+ / 8.5.12+.

What a scanner can and cannot tell you

An external scan catches items 1, 9, 10 and 11 in seconds, and reminds you about item 4 when it sees Supabase. It cannot see your RLS policies or your API authorization logic, because those only show up when someone actively tries to break them. For those, test as a second user, or ask someone who has not seen the code to try.

Scan your app now, fix what it finds, and scan again. If the report is longer than you have time for, a fix sprint covers keys, headers and server configuration in one pass.