🩹Vibe Code Fix

The Security Checks AI Coding Tools Skip by Default

Your AI assistant is optimized for 'it runs'. Security is a concern you have to bring to the conversation yourself. Here's what to explicitly ask for.

When you prompt Claude Code to "build a user login page", it builds a user login page. It does not, by default, build a user login page that resists credential stuffing, rate-limits failed attempts, validates email format server-side, or encrypts session tokens with a key that isn't hard-coded. Those things aren't part of "build a login page" as the model understands it.

You have to bring security to the conversation. Here's the explicit list I paste into prompts now for anything that touches user data.

Authentication Prompts

Before asking for login/signup code, I include:

  • "Rate-limit failed login attempts to 5 per IP per 15 minutes"
  • "Hash passwords with bcrypt at cost factor 12 minimum"
  • "Session tokens must be HTTPOnly, Secure, SameSite=Lax cookies"
  • "Email verification required before the account can take any action"
  • "Don't leak whether an email is registered — return the same response for unknown emails"

Without those explicit asks, you'll get a login form that accepts anything, stores passwords with MD5 "because it's simple", and tells attackers exactly which emails are in your database.

API Route Prompts

For any API route that mutates data:

  • "The route must validate the session at the top of the handler — before any other logic"
  • "Authorization check: the user can only modify their own records"
  • "Log the action with user ID and timestamp for audit"
  • "Return 401 for unauthenticated, 403 for unauthorized — never 200 with an error field"

The difference between "validate the session" and "use the auth system" is night and day. The first gets you a real check. The second gets you a // TODO: add auth comment.

Database Prompts

Before asking for any query with user input:

  • "Use parameterized queries — never concatenate user input into SQL"
  • "Explicitly list the columns in SELECT — no SELECT *"
  • "Wrap writes in transactions with proper rollback"
  • "Validate input with Zod before it touches the database"

"No SELECT *" sounds like a style issue. It isn't. It's how new sensitive columns (password hash, API key, PII) leak into API responses the moment they're added to the schema.

File Upload Prompts

File uploads are where things get spicy. Standard prompts I use:

  • "Validate MIME type and file extension on the server — never trust the client"
  • "Check file size before reading into memory"
  • "Store uploaded files outside the webroot with non-guessable names"
  • "Scan for PHP/executable content if the bucket is public"
  • "Set a max upload size at the web server layer, not just in the application"

Third-Party API Prompts

For any integration with Stripe, OpenAI, email providers, etc:

  • "The API key is in environment variables, not hardcoded or in any client-side file"
  • "Implement retry with exponential backoff for 429 and 5xx responses"
  • "Webhook signatures must be verified before processing"
  • "Never log the request body if it might contain PII or tokens"

Why This Is On You

It feels unfair that you have to list these things. Surely the AI knows? It does know — in the sense that if you ask "is it safe to concatenate user input into SQL?" it will correctly say no. But when you ask "build me a search feature", it defaults to the most concise implementation, which is almost never the most secure one.

The fix is to treat security requirements like any other requirement: write them down, paste them into the prompt, and verify them with the Vibe Code Fix checklist before shipping. The security section of the checklist has 6 items that catch most of what gets missed.

You might also like

Ready to run your next diff through the checklist?

Back to checklist