Why AI generated code is structurally insecure
Lovable, Bolt, and Cursor optimise for "it works". Security is implicit, not explicit. The AI knows how to enable Row Level Security, but if you do not ask, neither does it. The default is the path of least resistance, which usually means security off.
Add to that: vibecoders often do not know what to check for. You only know RLS is off if you know what RLS is.
The five most common vulnerabilities
1. Exposed secrets
API keys (OpenAI, Stripe, Supabase) ending up in the frontend bundle. Anyone visiting your site can grab them from browser DevTools and use them. The bill arrives next morning.
Fix: all secrets in server side environment variables, never in client code. Rotate any keys that ever touched code.
2. Missing Row Level Security on Supabase or Firebase
A logged in user can pull every other user's data, not just their own. The single most common incident in vibe coded apps in 2025.
Fix: enable RLS on every table. Define policies per table: auth.uid() = user_id at minimum.
3. No authentication on API routes
Endpoints like /api/admin/users reachable without login. An attacker just guesses the URL.
Fix: every server side route validates the session or token before responding.
4. Injection through unvalidated input
User input flowing directly into a query or API call without validation. Older than the web itself, still common in AI generated code.
Fix: use parameterised queries (every modern ORM does this by default). Validate and sanitise everything coming from a user.
5. No rate limiting
An API endpoint that accepts ten requests per second. One malicious user runs your AI bill or database into the ground.
Fix: rate limit per IP or per user. Cloudflare does this free at the edge. Vercel and Railway have built in options.
OWASP Top 10 translated to vibe coding
| OWASP risk | Vibe coding context |
|---|---|
| A01 Broken Access Control | No RLS, no route auth |
| A02 Cryptographic Failures | Plain text passwords, secrets in code |
| A03 Injection | SQL injection, prompt injection in AI features |
| A05 Security Misconfiguration | Default Supabase keys, debug mode in production |
| A07 Identification Failures | No login rate limit, no 2FA option |
A pre launch security checklist
- All secrets in environment variables, not in code
- RLS enabled on every database table with user data
- Auth check on every server side endpoint
- Input validation on every form (Zod, Joi, or equivalent)
- Rate limiting on auth and heavy endpoints
- HTTPS everywhere (no mixed content)
- CSP headers configured
- Dependencies scanned for known CVEs (npm audit or Snyk)
- Database backups, automatic
- Privacy policy and cookie banner if EU
Why a human still beats automated tools
Automated security scanners (npm audit, Snyk) catch known CVEs. They miss logical holes: an endpoint returning data from other users is technically not a "security vulnerability" to a scanner, but it is a data leak.
That is why Ployed runs human in the loop deployment. An engineer reads your code before live, catches this category of issues, then ships. Read more about human in the loop AI coding or managed deployment for AI apps.