The vibe-coded app security checklist (2026)
AI builders are great at getting an app working fast. They're less great at the boring stuff nobody asked for: locking down the database, keeping secrets out of the browser, and adding security headers. That isn't a knock on the tools. It's just that "make it work" and "make it safe on the open internet" are different prompts.
This is the checklist I'd run on any app built with Lovable, Bolt, Cursor, v0 or similar before sharing it. Each item says what to check, how to check it, and what to do if it fails. Most of it you can do yourself in under an hour.
1. Secrets and API keys
The rule: anything that ships to the browser is public. That includes every JavaScript file your site loads.
Check:
- Open your live site, then DevTools → Sources → search all files (Ctrl+Shift+F / Cmd+Opt+F).
- Search for
sb_secret_,service_role,sk_live,sk-,AKIA(AWS access key prefix), and the wordsecret. - Check your repo too: is
.envin.gitignore? Search your git history if you ever committed it.
What's fine: Supabase publishable keys (sb_publishable_...) and the legacy anon key. Supabase says publishable keys are safe to expose because they only reach what Row Level Security allows. (Supabase docs: API keys)
If it fails: rotate the key in the provider's dashboard first (assume it's already been copied), then move the call server-side (an Edge Function, API route or serverless function) and keep the key in environment variables or your builder's secrets store. Lovable, for example, has a Secrets feature for this. (Lovable docs: Security)
2. Database access rules
If your app uses Supabase (most Lovable and many Bolt apps do), this is the most important section.
The rule: Supabase's docs say "A table in an exposed schema without RLS is readable and writable by any role with a grant on it," and tell you to enable RLS on every table in an exposed schema. (Supabase docs: Row Level Security)
Check:
- Run the Security Advisor in your Supabase dashboard and fix every error it reports. (Supabase docs: Advisors)
- Look for policies with
using (true)on anything that isn't meant to be public. - Check insert/update policies have a
with checkclause. Supabase notes thatwith check"ensures that any new row adheres to the policy constraints, so a user cannot create a row that belongs to someone else." - Supabase also warns that adding policies doesn't remove grants. On older projects that grant
anonandauthenticatedby default, revoke what you don't need.
If it fails: enable RLS and add policies scoped to the user, for example using ((select auth.uid()) = user_id).
Using Firebase instead? The same idea applies to Firestore and Storage Security Rules. Make sure they aren't left in test mode (open to everyone).
3. Auth and private pages
Check:
- Visit
/admin,/dashboard,/settingsand any API routes while signed out. You should be redirected or get a 401/403, not data. - Do the two-account test: as user B, try to load user A's records by changing IDs in URLs or requests.
- Hiding a button in the UI isn't access control. The check has to happen on the server or in the database (RLS).
If it fails: add the auth check where the data is served, not just in the frontend route.
4. HTTPS, security headers and cookies
Check (DevTools → Network → click your page request → Response Headers):
- The site redirects
http://tohttps://, and the certificate is valid. Strict-Transport-Securityis set.Content-Security-Policyexists, even a basic one.X-Frame-Options: DENYor CSPframe-ancestors 'none'(or a list of sites you trust).X-Content-Type-Options: nosniffand aReferrer-Policy.- Cookies (Application tab → Cookies): session cookies should have
Secure,HttpOnlyand aSameSitevalue.
Reference for every header: MDN HTTP headers. For cookie attributes: MDN Set-Cookie.
If it fails: add headers in your host's config (most hosts support a headers file or settings panel), or ask your AI builder to add them, then re-check that nothing broke. A strict CSP can block your own scripts, so test after adding it.
5. Exposed files and debug output
Check:
- Visit
/.env,/.git/HEAD,/.git/config, and any/backup.zipor.sqlfiles you might have uploaded. All should 404. - Open a URL that doesn't exist and trigger an error (e.g., submit a bad form). No stack traces, file paths or SQL in the response.
- Look for source maps (
.mapfiles) in production if you don't want your original source easy to read.
If it fails: fix your build output or deploy settings so only the built app is served.
6. CORS and third-party scripts
Check:
- Your own API shouldn't return
Access-Control-Allow-Origin: *together with credentials. If your API uses cookies or auth headers, allow only your own domain. - List every third-party script your page loads (Network tab, filter by JS). Remove ones you don't use, and pin versions where possible.
7. Dependencies
Check:
- If you have the code (Cursor, or Lovable/Bolt synced to GitHub), run
npm auditand update anything flagged critical or high. - Turn on GitHub's Dependabot alerts if your repo is on GitHub.
8. Non-security launch basics (they're cheap)
Not security, but they're on the same "embarrassing on launch day" list:
- Page title and description set on every page, and the site isn't accidentally set to
noindex. - No broken links or images.
- If you send email from your domain, SPF and DMARC records exist, so your emails don't land in spam.
- Basic accessibility: images have alt text, buttons have labels, text has enough contrast.
9. Re-check after every big AI change
This is the one people skip. AI builders regenerate code. A prompt that adds a feature can quietly drop a policy, move a key into the frontend, or remove a header. Re-run the quick checks (sections 1, 2 and 5 at least) after any large change, and always before you share a new version.
The one-page version
- No secret keys in JS bundle or repo
- RLS on every exposed table; Security Advisor clean
- No
using (true)on private data; inserts havewith check - Private pages and APIs reject signed-out users; two-account test passes
- HTTPS forced; HSTS, CSP, frame protection, nosniff, Referrer-Policy set
- Session cookies are Secure, HttpOnly and SameSite
/.envand/.gitreturn 404; no stack traces- CORS limited to your domain if credentials are used
npm auditclean of critical/high- Titles, links, SPF/DMARC and alt text checked
- Re-checked after the last big AI change
Want it run for you?
Everything above can be done by hand, and it's worth doing once just to learn your app. If you'd rather have the outside-in parts checked automatically, PreFlight runs 65 checks on your live site (security, speed, search, links, email setup and accessibility). The first scan of each site is free and gives you your score plus your top 3 fixes in full. The full report is a one-time $19 (or $49 for 3 scans, $69 for 5), with a 14-day refund on unused scans. No subscription.