Vibecoding is fast. You describe what you want, the AI builds it, and you ship. But every feature you add without reviewing the security implications is a door you forgot to lock.
Most vibecoded apps share the same vulnerabilities - missing auth checks, leaked error messages, race conditions on payment flows, unsanitized file uploads. Not because the AI is bad at security, but because nobody asked it to think about security.
One prompt changes that.
The prompts
Here are three prompts you can use depending on how deep you want to go. Start with the first one if you have never audited your app. Use the second for a focused deep dive. Use the third to build security into your regular workflow.
Prompt 1 - Full audit (recommended for first time)
Do a complete security audit of my app like a professional whitehat hacker. Use plan mode.
Cover these areas:
- Authentication and authorization (missing auth checks, session handling, privilege escalation)
- API route security (input validation, rate limiting, error message leaks)
- Injection vulnerabilities (XSS, SVG injection, SQL injection, command injection)
- File upload security (type validation, size limits, malicious content)
- Payment and billing logic (race conditions, webhook verification, credit bypass)
- Dependencies (npm audit, known CVEs)
- Security headers (CSP, HSTS, X-Frame-Options)
- Secrets management (hardcoded keys, env variable exposure)
For every finding: state the severity, the exact file and line number, the attack scenario, and the fix.
Prioritize by severity. Then fix everything, starting with critical issues.
Prompt 2 - Targeted deep dive
Act as a penetration tester. Focus specifically on race conditions and business logic flaws in my app.
Look for:
- TOCTOU (time-of-check-time-of-use) bugs in credit systems, usage limits, and payment flows
- Check-then-act patterns where concurrent requests can bypass limits
- Endpoints where the check and the action happen in separate API calls
- Webhook handlers that are not idempotent
- Any read-then-write pattern without database-level locking
For each finding, show me a concrete attack scenario with parallel requests and provide an atomic fix.
Prompt 3 - Quick pre-deploy check
I am about to deploy. Do a quick security sanity check:
1. Run npm audit and summarize high/critical vulnerabilities
2. Check all API routes for missing authentication
3. Check for any error responses that leak internal details (error.message, stack traces)
4. Verify rate limiting exists on all public-facing endpoints
5. Check that no secrets are hardcoded or exposed via NEXT_PUBLIC_ prefixed env vars
6. Check file uploads for missing type/size validation
Keep it concise. Flag only real issues, not theoretical concerns.
Why plan mode matters
When you activate plan mode, Claude Code does not start changing files immediately. It reads first. It explores your codebase with multiple parallel agents, maps out the architecture, identifies every relevant file, and then presents you with a structured plan before touching anything.
This matters for security because:
- You see the full picture before any changes happen. A security audit that silently edits files is risky - you want to review what was found and approve what gets fixed.
- The AI goes deeper. In plan mode, it launches dedicated exploration agents that search across your entire codebase simultaneously. One agent checks auth, another checks API routes, a third checks dependencies. This is more thorough than a linear conversation.
- You stay in control. You approve the plan, then the AI executes it. If a finding is a false positive or a design choice, you can skip it before any code changes.
To activate plan mode, type /plan in Claude Code before sending your prompt. Or add "Use plan mode" to the prompt itself.
The iteration workflow
A security audit is not a one-shot fix. Some changes break things. Some fixes reveal new issues. Here is the workflow that actually works:
Step 1 - Run the audit in plan mode. Let Claude explore and present findings. Review them.
Step 2 - Approve and let it fix. Exit plan mode so Claude implements the fixes.
Step 3 - Start your dev server and test.
npm run dev
Open http://localhost:3000 in your browser. Click through the app. Test the flows that were flagged - login, file uploads, payment, API calls. Make sure nothing is broken.
Step 4 - Run the next round. Once localhost looks good, tell Claude:
Do another security pass. Focus on what we might have missed - race conditions, business logic, edge cases. Think like an attacker.
This second round catches the deeper issues that only surface after the obvious vulnerabilities are patched.
Step 5 - Build and verify.
npm run build
A clean build with zero TypeScript errors confirms nothing is structurally broken.
Repeat steps 3 through 5 until you are satisfied. Two to three rounds usually covers everything.
The most common vulnerabilities in vibecoded apps
After auditing multiple apps built with AI, the same patterns keep showing up. If you are vibecoding, check for these first.
Missing authorization checks
The AI builds a working endpoint but forgets to verify that user A cannot access user B's data. A delete endpoint that takes an ID parameter but does not check ownership is the most common version of this.
What to look for: Any API route that accepts an ID from the request. Does it filter by the authenticated user's ID?
Error messages that leak internals
When something fails, the API returns the raw database error to the client. This exposes table names, column names, and sometimes query structure.
What to look for: Any error.message being returned in a JSON response. Replace with a generic message and log the details server-side.
Race conditions on credits and limits
A usage check and a usage increment happen in two separate API calls. Between the check and the increment, five parallel requests all pass the check. The user burns through their limit.
What to look for: Any pattern where you read a counter, check it, and then write to it in a separate call. These need to be combined into a single atomic database operation with row locking.
Unsanitized file uploads
SVG files can contain JavaScript. Image uploads trust the MIME type header instead of checking the actual file bytes. There is no size limit or no server-side validation at all.
What to look for: Every file upload endpoint. Does it validate file type by content (magic bytes), not just the header? Does it enforce a size limit? If it accepts SVGs, does it sanitize them?
Secrets in client-side code
Environment variables prefixed with NEXT_PUBLIC_ are bundled into the browser. A dev bypass flag or an API key with that prefix is visible to anyone who opens the browser devtools.
What to look for: Every NEXT_PUBLIC_ variable. Is it safe to be public? Service role keys, webhook secrets, and dev-only flags should never have this prefix.
Vulnerable dependencies
The app ships with known CVEs in the dependency tree because nobody ran npm audit. Some of these are high severity with published exploits.
What to look for: Run npm audit right now. Fix what you can with npm audit fix. Review the rest manually.
No rate limiting
Every public endpoint can be called thousands of times per second. Signup, login, file upload, payment - all unprotected. This enables brute force attacks, spam, and resource exhaustion.
What to look for: Does every endpoint that accepts user input have a rate limit? Use IP-based limits for public routes and user-based limits for authenticated routes.
Make it a habit
Security is not something you do once and forget. Every new feature introduces new attack surface. Here is a simple rhythm:
- Before every deploy - Run prompt 3 (the quick sanity check). Takes two minutes.
- Every two weeks - Run prompt 1 (the full audit). Review findings, fix what matters.
- After major features - Run prompt 2 (the targeted deep dive) on the area you just built.
The entire audit is free if you are already using Claude Code. There is no reason not to do it.
Getting started
Copy prompt 1 above, switch to plan mode, and paste it in. Review the findings. Approve the plan. Test on localhost. Iterate. Your app will be meaningfully more secure in a single session.