The Vibe Coding Security Checklist (2026): Ship Fast, Stay Safe
A complete security checklist for developers shipping AI-built apps. 20 checks across secrets, auth, injection, XSS, and configuration. Print it, pin it, use it.
You built your app with AI. It works. Users can sign up, create data, and do what they need to do. Now you need to make sure it is secure before you ship it.
This checklist covers the 20 most critical security checks for AI-generated applications. It is based on our analysis of hundreds of apps built with Cursor, Lovable, Bolt.new, and other AI tools, cross-referenced with the OWASP Top 10 and the Stanford AI code security research.
Print it. Pin it next to your monitor. Run through it before every deploy.
Secrets Management
Hardcoded secrets are the easiest vulnerability for attackers to exploit and the most common in AI-generated code.
- 1
No hardcoded API keys, tokens, or passwords in source code
Search your codebase for strings matching common key patterns: sk_live_, sk-proj-, SG., ghp_, Bearer, password=. Every secret must come from an environment variable, not a string literal.
CWE-798: Hard-coded Credentials - 2
No secrets in client-side environment variables
Variables prefixed with VITE_, NEXT_PUBLIC_, or REACT_APP_ are bundled into client JavaScript and visible to anyone. Only truly public values (Supabase anon key, public API URLs) should use these prefixes.
CWE-200: Exposure of Sensitive Information - 3
.env is in .gitignore
Verify that .env, .env.local, and .env.production are listed in your .gitignore file. Run git log --all --full-history -- .env to check if any env files were ever committed. If they were, rotate every secret in them immediately.
- 4
Supabase service role key is server-side only
The service_role key bypasses all Row Level Security. It must never appear in client code. Use it only in Supabase Edge Functions or server-side API routes. The anon key is safe for client use.
CWE-250: Execution with Unnecessary Privileges
Authentication & Authorization
Broken access control is the #1 vulnerability category in the OWASP Top 10. AI tools get this wrong more than anything else.
- 5
Every API route has authentication middleware
No API endpoint that accesses user data should be callable without a valid session or token. Apply auth middleware at the router level so new routes are protected by default.
CWE-306: Missing Authentication - 6
Auth conditions are not inverted
Manually verify that your auth guards redirect/reject when there is NO session (if (!session)) rather than when there IS a session (if (session)). This inversion is found in 31% of Cursor-built apps.
CWE-863: Incorrect Authorization - 7
Database queries are scoped to the authenticated user
Every findUnique, update, and delete call should include a userId or organizationId constraint from the session. Never trust a user-supplied ID without verifying ownership. This prevents IDOR attacks.
CWE-639: Insecure Direct Object Reference - 8
Role checks are enforced server-side, not just in the UI
Frontend role checks (hiding admin buttons, redirecting non-admins) are for UX only. Every privileged API endpoint must independently verify the user's role from the server-side session.
CWE-862: Missing Authorization - 9
Supabase RLS is enabled on every table with policies defined
In the Supabase dashboard, every table storing user data should show 'RLS Enabled'. Each table needs SELECT, INSERT, UPDATE, and DELETE policies scoped to auth.uid(). Tables without RLS are fully accessible to any authenticated user.
- 10
Password reset and magic link flows are verified
Test that password reset tokens expire, cannot be reused, and are invalidated when a new one is generated. Verify that magic links have a short expiry (10-15 minutes) and are single-use.
Injection Prevention
Injection has been in the OWASP Top 10 since its creation. AI tools frequently generate injection-vulnerable code when implementing search, filtering, and dynamic queries.
- 11
No string interpolation in SQL queries
Search for $queryRawUnsafe, string concatenation in queries, or template literals building SQL strings. Use your ORM's query builder or parameterized queries ($queryRaw with tagged templates in Prisma).
CWE-89: SQL Injection - 12
All user input is validated with a schema library
Every form submission and API endpoint should validate input with Zod, Yup, or joi. Check for type correctness, length limits, format patterns (email, URL), and allowed values (enums). Validate on both client and server.
CWE-20: Improper Input Validation - 13
No shell command execution with user input
Search for exec(), spawn(), or system() calls that include user-supplied data. If shell commands are necessary, use a whitelist of allowed commands and never pass user input directly.
CWE-78: OS Command Injection
XSS Protection
Cross-Site Scripting allows attackers to execute JavaScript in your users' browsers, stealing sessions, credentials, and data.
- 14
No dangerouslySetInnerHTML with user-generated content
Search for dangerouslySetInnerHTML in your React codebase. If it renders content that users can control (comments, profile bios, messages), it is an XSS vector. Use a sanitization library like DOMPurify if you must render HTML.
CWE-79: Cross-Site Scripting - 15
Content-Security-Policy header is set
Add a CSP header that restricts script sources. At minimum: script-src 'self'. This prevents inline script injection even if an XSS vector exists. Test with the browser console for CSP violations before deploying.
- 16
User-generated URLs are validated
If users can provide URLs (profile links, redirect targets, image sources), validate that they start with https:// and do not use javascript: or data: protocols. These can execute arbitrary JavaScript.
CWE-601: Open Redirect
Configuration & Infrastructure
Security misconfigurations are silent. Your app works perfectly while being completely exposed.
- 17
CORS is restricted to your frontend domain
Search for cors({ origin: "*" }) or Access-Control-Allow-Origin: *. Replace with your specific frontend domain(s). Wildcard CORS allows any website to make authenticated requests to your API.
CWE-942: Overly Permissive CORS - 18
Rate limiting is enabled on auth and API endpoints
Apply strict rate limits (5-10 requests/15 min) on login, registration, and password reset. Apply moderate limits (100 req/15 min) on general API routes. Use express-rate-limit for Express or @upstash/ratelimit for serverless.
CWE-770: Resource Allocation Without Limits - 19
Error responses do not expose stack traces or internal details
In production, error responses should return generic messages ("Something went wrong") without stack traces, file paths, database table names, or query details. Check your global error handler.
CWE-209: Error Message Information Leak - 20
Session cookies have secure attributes
All session cookies must have: httpOnly: true (prevents JS access), secure: true (HTTPS only), sameSite: "lax" or "strict" (prevents CSRF). Check your authentication library configuration.
CWE-614: Sensitive Cookie Without Secure Flag
Quick Reference: Search Commands
Use these grep commands to quickly check for the most common issues in your codebase:
# Check for hardcoded secrets
grep -rn "sk_live_|sk-proj-|sk_test_|SG.|ghp_" --include="*.ts" --include="*.tsx" --include="*.js"
# Check for service role key in client code
grep -rn "service_role" --include="*.ts" --include="*.tsx" src/
# Check for dangerous HTML rendering
grep -rn "dangerouslySetInnerHTML" --include="*.tsx" --include="*.jsx" src/
# Check for raw SQL queries
grep -rn "queryRawUnsafe|\$queryRaw`" --include="*.ts" --include="*.js" src/
# Check for permissive CORS
grep -rn 'origin.*"\*"|origin.*\*' --include="*.ts" --include="*.js" src/
# Check for missing RLS (Supabase migrations)
grep -rn "CREATE TABLE" --include="*.sql" supabase/migrations/
# Then verify each table has ENABLE ROW LEVEL SECURITY
# Check for exposed env vars
grep -rn "VITE_.*SECRET|VITE_.*KEY|NEXT_PUBLIC_.*SECRET" .env*Automate This Checklist
Running through 20 items manually before every deploy is tedious and error-prone. That is why we built ShipSafe.
ShipSafe automates detection for 18 of these 20 checklist items. Paste your GitHub URL, and in under two minutes you get a detailed report covering every vulnerability found, its severity, the exact file and line number, and a specific code fix.
The two items that require manual review — verifying auth condition logic and testing password reset flows — are flagged by ShipSafe with guidance on what to look for. Use ShipSafe for automated coverage and reserve your manual review time for the high-judgment security decisions.
Further Reading
This checklist covers the essentials. For deeper dives into specific tools and vulnerability categories, see:
- Is Cursor-Generated Code Secure? We Scanned 100 Repos to Find Out
- 5 Security Vulnerabilities Every Lovable App Has
- Bolt.new Security Guide: How to Ship Without Getting Hacked
- AI-Generated Code Security: The Risks Nobody Talks About
- OWASP Top 10 (2021)
- Stanford: Do Users Write More Insecure Code with AI Assistants?
Want to check your own app?
Paste your GitHub URL and get a security report in under 2 minutes. Free scan, no credit card required.
Scan My App Free