Every week we audit AI-generated codebases at Fortivibe, and every week we see the same seven mistakes. Not similar mistakes. The same seven, on repeat, across Cursor projects, Lovable projects, Bolt projects, and everything in between.
Here they are, roughly ordered by how badly they hurt when they go wrong.
1. Trusting the client
The single most common bug in vibe-coded apps is trusting a value that came from the browser. A user's role, a price, an item ID they "own" — all of it gets read straight from the request body and used as if it were authoritative.
// The bug we see literally every week.
app.post('/api/checkout', async (request, response) => {
const { user_id, price_cents, cart } = request.body;
await charge_card({ user_id, amount: price_cents });
await create_order({ user_id, cart });
});The user picks the price. The user picks the user_id. You are not running a store; you are running a donation form where the donor sets the amount.
2. Missing authorization checks
Authentication (are you logged in?) is not the same as authorization (are you allowed to touch this row?). LLMs love to add the first and forget the second.
If your endpoint looks up a record by ID from the URL and returns it without checking ownership, congratulations — you shipped an IDOR.
3. Secrets in the client bundle
If your Stripe secret key, your OpenAI key, or your database URL is visible in the JavaScript bundle sent to the browser, it is not a secret anymore. It is a public string with a bill attached.
How to check
Run this in your project root:
grep -r "sk_live" ./dist ./build ./public 2>/dev/null
grep -r "OPENAI_API_KEY" ./dist ./build ./public 2>/dev/nullIf anything comes back, rotate the key right now and read the rest of this post later.
4. No rate limiting anywhere
Signup, login, password reset, "contact us", the AI endpoint that costs you 4 cents per call — none of them have rate limits. The first bored teenager with a Python script will find this within a week of your launch.
5. CSRF? Never heard of her
Cookie-authenticated endpoints without CSRF tokens are wide open to any site that can trick a logged-in user into visiting it. AI codegen tools ship this bug by default.
6. SQL injection via string concatenation
Yes, in 2026. LLMs still occasionally generate this:
const rows = await db.query(`SELECT * FROM users WHERE email = '${email}'`);Use parameterized queries. Always. There is never a reason not to.
7. Verbose error responses in production
Full stack traces, database driver messages, and file paths returned to the client are a map of your infrastructure. Catch, log server-side, return a generic message.
If any of these sound like your app, book an audit and we'll find the rest of them for you.