Skip to main content
All posts
vibe-codingsecuritychecklistcursorlovablebolt

Vibe Coding Security Checklist: 15 Things to Check Before You Ship

April 16, 202612 min read

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

Scan your app free

Paste a URL, get a letter grade and Cursor-ready fixes in 3 minutes. No signup required.

Start Free Scan