← Cheatsheets / Security

Security Checklist for AI-Generated Code

Quick-reference security checklist. Run through this before shipping any AI-generated code to production.

security checklist production vulnerabilities

AI writes fast. You make it safe. Run through this checklist before every deploy.

Companion to the full Security for Vibecoders guide.


🔑 Secrets & Configuration

CheckWhyHow to Fix
No hardcoded passwords, API keys, or tokens in codeBots scrape GitHub for secrets within minutes of pushingMove to .env file + process.env / os.environ
.env is in .gitignorePrevents accidentally committing secretsAdd .env and .env.* to .gitignore
No secrets in frontend/client-side codeBrowser code is visible to everyoneMove to server-side API routes; use NEXT_PUBLIC_ only for non-secret values
Different secrets for dev/staging/productionCompromise in dev shouldn’t affect productionUse separate .env files or environment-specific config
Run gitleaks detect before pushingCatches any secrets that slipped throughInstall gitleaks, add as pre-commit hook

🔐 Authentication & Authorization

CheckWhyHow to Fix
Passwords hashed with bcrypt or argon2Plain text/MD5/SHA passwords are trivially crackedbcrypt.hash(password, 12) — never store plain text
JWT tokens have expirationTokens without expiry are permanent access keysjwt.sign(payload, secret, { expiresIn: '24h' })
Auth checked on server, not just clientClient-side checks are trivially bypassedAdd middleware to every protected API route
Rate limiting on login/signupPrevents brute force attacksUse express-rate-limit or similar: 5 attempts/min
Session invalidation on password changeOld sessions should die when password changesClear all sessions/tokens for user on password update
No custom auth cryptoRoll-your-own auth is always brokenUse NextAuth, Passport.js, Auth0, Supabase Auth, Clerk

✅ Input Validation

CheckWhyHow to Fix
All input validated on the serverClient validation is UX, server validation is securityUse Zod, Joi, or Yup on every API endpoint
SQL queries use parameterized statementsString concatenation = SQL injectionUse $1 params or ORM (Prisma, Drizzle)
HTML output escapedUnescaped user input = XSS attacksUse framework defaults (React auto-escapes); sanitize with DOMPurify if using dangerouslySetInnerHTML
File uploads validatedMalicious files can execute code on serverCheck file type (magic bytes, not just extension), enforce size limits, store outside webroot
URL redirects use allowlistOpen redirects enable phishingOnly redirect to known paths: if (allowedUrls.includes(url))
Request body size limitedLarge payloads can crash your serverapp.use(express.json({ limit: '1mb' }))

📦 Dependencies

CheckWhyHow to Fix
npm audit / pip audit cleanKnown vulnerabilities in your dependency treeRun npm audit fix or update vulnerable packages
Lock file committedEnsures consistent builds; prevents supply chain attacksCommit package-lock.json / poetry.lock / pnpm-lock.yaml
No unnecessary packagesEach dependency is an attack surfaceRemove unused packages; prefer built-in APIs
Check for typosquattingAttackers publish expres instead of expressVerify package names, check download counts and publisher
Dependabot or Renovate enabledAutomated alerts for vulnerable dependenciesEnable in GitHub repo settings (free)

🚀 Deployment

CheckWhyHow to Fix
HTTPS enforcedHTTP traffic is readable by anyone on the networkUse platform SSL (Vercel, Railway auto-enable) or Let’s Encrypt
Security headers setPrevents clickjacking, XSS, MIME sniffingAdd CSP, HSTS, X-Frame-Options, X-Content-Type-Options
Debug mode OFFDebug mode exposes stack traces, source maps, internal stateEnsure NODE_ENV=production; remove DEBUG=*
Error messages are genericDetailed errors help attackers understand your systemReturn “Something went wrong” to users; log details server-side
Database not publicly accessiblePublic DB = anyone can connectUse private networking; require SSH tunnel or VPN for access
CORS restricted to your domainsorigin: '*' lets any site make requests to your APIAllowlist your specific domains
Admin routes protectedExposed admin panels are the #1 way apps get compromisedAuth + IP restriction + separate subdomain

🏃 Quick Commands

# Scan for secrets
gitleaks detect
trufflehog git file://.

# Audit dependencies
npm audit
pip audit

# Security linting
npx eslint --plugin security .
semgrep --config=p/owasp-top-ten .

# Check security headers (after deploy)
curl -I https://yoursite.com | grep -i "security\|strict\|x-frame\|x-content\|csp"

🤖 Security Prompt Templates

Before generating code:

“Use environment variables for all secrets. Validate all input with Zod. Use parameterized queries. Add rate limiting to auth endpoints.”

After generating code:

“Review this code for OWASP Top 10 vulnerabilities. Check for: SQL injection, XSS, hardcoded secrets, missing auth, insecure defaults.”

Before deploying:

“Generate security headers middleware for Express/Next.js. Include: CSP, HSTS, X-Frame-Options, X-Content-Type-Options. Restrict CORS to [my domain].”

✓ Copied to clipboard!