Vibe Coding Security Checklist: 15 Things to Check Before You Ship
We have scanned thousands of apps built with Cursor, Lovable, Bolt, and v0. The same vulnerabilities appear over and over. This checklist is ordered by severity — Tier 1 issues can get your users' data stolen today, Tier 2 issues make attacks easier, and Tier 3 is noise most scanners fixate on.
Print this. Tape it next to your monitor. Run through it before every deploy.
Tier 1: Can Someone Steal Data Right Now?
If you fail any of these, stop shipping and fix it. These are the checks that separate "oops" from "data breach."
1. No secrets in client-side code
Open DevTools on your deployed site. Go to Sources. Search for sk_live, service_role, OPENAI, or SECRET. If anything shows up, your secrets are in the JavaScript bundle that every visitor downloads.
Fix: Move the key to a server-side API route. Remove the NEXT_PUBLIC_ prefix. Rotate the exposed key immediately — it is already compromised if your app has been live for any amount of time.
2. Row Level Security is enabled AND has correct policies
Having RLS "enabled" is not enough. We find three failure patterns constantly: tables with RLS enabled but zero policies (blocks everything, so devs disable it), policies with USING(true) (grants access to every role including anon), and UPDATE policies missing WITH CHECK (lets users escalate their own role).
Test it: Open your browser console on your live site and run supabase.from('profiles').select('*') with just the anon key. If you see other users' data, your RLS is broken.
3. No admin routes accessible without authentication
AI tools love creating /admin, /dashboard, and /api/admin/* routes. They almost never protect them. Try visiting your admin pages in an incognito window. If they load, anyone can access them.
Fix: Add auth middleware that redirects unauthenticated users. In Next.js, use middleware.ts to protect route groups.
4. No direct database access from the client
If your frontend code calls supabase.from('table').insert() with data the user controls, and your RLS is weak, an attacker can insert, modify, or delete any row. The client should only talk to your API routes, which validate and sanitize before touching the database.
5. Authentication tokens are not in URLs
Some AI-generated auth flows put tokens in query parameters like ?token=abc123. These end up in server logs, browser history, referrer headers, and analytics tools. Check your auth flow — tokens belong in HTTP-only cookies or Authorization headers, never in URLs.
Tier 2: Are Your Defenses Solid?
These do not prove someone can steal data today, but they make attacks significantly easier.
6. HTTPS everywhere, no mixed content
Your site loads over HTTPS, but does it load any images, scripts, or API calls over plain HTTP? Mixed content downgrades your security. Check the browser console for "Mixed Content" warnings.
7. Content-Security-Policy header exists
Without CSP, any XSS vulnerability becomes an instant data exfiltration. With CSP, even if an attacker finds XSS, they cannot load external scripts or send data to their server. A loose CSP is infinitely better than none.
8. Rate limiting on login and sensitive endpoints
Without rate limiting, an attacker can try thousands of passwords per minute. They can also abuse your OpenAI or Stripe API through your unprotected endpoints, running up your bill.
Minimum: 5 attempts per minute on login. 60 requests per minute on API routes. Use Upstash, Cloudflare, or Vercel's built-in rate limiting.
9. CORS restricted to your domain
If your API returns Access-Control-Allow-Origin: *, any website can make authenticated requests to your API on behalf of your logged-in users. Restrict CORS to your own domain unless you are intentionally building a public API.
10. Session cookies have Secure, HttpOnly, SameSite flags
Without HttpOnly, JavaScript can read your session cookies (XSS becomes session hijacking). Without Secure, cookies transmit over HTTP. Without SameSite=Lax, CSRF attacks can use your cookies.
11. Error messages do not leak stack traces
AI tools often leave console.error and detailed error responses in production. Stack traces reveal your file structure, database schema, and library versions — exactly what attackers need for targeted exploits.
Tier 3: Good Hygiene (Not Urgent)
Traditional scanners obsess over these. They are real things, but they are not how apps get hacked. Fix them when you have time, not instead of Tier 1 and 2.
12. X-Frame-Options or frame-ancestors CSP
Prevents your site from being embedded in an iframe on a malicious site. Matters for clickjacking, which requires a very specific attack scenario.
13. X-Content-Type-Options: nosniff
Prevents browsers from MIME-type sniffing. A defense-in-depth header that matters in edge cases.
14. Server version not disclosed
Your Server: nginx/1.24.0 header tells attackers exactly which CVEs to try. Remove it, but do not pretend this alone is security.
15. Subresource Integrity on CDN scripts
If you load scripts from a CDN, SRI hashes ensure a compromised CDN cannot inject malicious code. Important if you use third-party scripts, less relevant if everything is bundled.
The Pattern We See
Most vibe-coded apps fail 4-7 items on this checklist. The distribution is predictable: 1-2 Tier 1 issues (usually exposed secrets or broken RLS), 3-4 Tier 2 issues (missing CSP and rate limiting are almost universal), and a handful of Tier 3 items that do not matter much.
The path from F to A is usually fixing 3-5 things. Start at the top of this list and work down. Do not waste time on Tier 3 until Tier 1 and 2 are clean.
Frequently Asked Questions
How often should I run through this checklist?
Before every production deploy. AI tools can reintroduce vulnerabilities you already fixed — they do not remember your security context between prompts.
My app passed all 15 checks. Am I safe?
This checklist covers the most common issues. There are dozens more: business logic flaws, insecure direct object references, race conditions, payment tampering. A checklist catches the obvious. A penetration test catches the rest.
Which vibe coding tools produce the most secure code?
None of them are secure by default. Lovable recently added built-in scanning (partnership with Aikido), which helps. But every tool we have tested — Cursor, Bolt, v0, Lovable — produces code that fails multiple items on this checklist out of the box.
Related reading
- The 7 Most Common Vulnerabilities in AI-Generated Code
45-62% of AI-generated code contains security flaws. These are the 7 specific vulnerabilities we find most often in apps...
- 5 Security Fixes Every Vibe Coder Should Know
Your AI-built app probably has at least one of these vulnerabilities. Here are 5 Cursor-ready fixes you can paste right ...
- The Supabase RLS Mistake That Could Expose Your Users' Data
USING(true) on a service-role policy sounds right but grants access to every role, including anon. Here are the 3 most c...
- Vibe Coding Security Risks — The Complete 2026 Guide
- Benchmark Scores — See how we validate our scanner
Scan your app free
Paste a URL, get a letter grade and Cursor-ready fixes in 3 minutes. No signup required.
Start Free Scan