Waarom AI code structureel onveilig is
Lovable, Bolt en Cursor optimaliseren voor "het werkt". Security is impliciet, niet expliciet. De AI weet wel hoe RLS aanstaat, maar als jij er niet om vraagt, vraagt de AI het ook niet aan jou. De default is "minste weerstand" en dat is meestal "veiligheid uit".
Daarbij komt: vibecoders weten vaak niet wat ze moeten controleren. Je weet pas dat je RLS uit hebt staan als je weet wat RLS is.
De vijf meest voorkomende kwetsbaarheden
1. Exposed secrets
API keys (OpenAI, Stripe, Supabase) die in de frontend bundle terecht komen. Iedereen die je site bezoekt kan ze uit de browser DevTools halen en gebruiken. Volgende dag krijg je de factuur.
Fix: alle secrets in environment variables aan de server side, nooit in client code. Roteer keys die ooit in code hebben gestaan.
2. Geen Row Level Security op Supabase of Firebase
Een ingelogde gebruiker kan alle data van alle gebruikers ophalen, niet alleen zijn eigen. Hét meest voorkomende incident bij vibe-coded apps in 2025.
Fix: RLS aanzetten op elke tabel. Policies definieren per tabel: auth.uid() = user_id als minimum.
3. Geen authentication op API routes
Endpoints zoals /api/admin/users die zonder login bereikbaar zijn. Een aanvaller probeert simpelweg de URL.
Fix: elke server-side route checkt de session of token voor hij iets terugstuurt.
4. SQL injection of vergelijkbare input attacks
User input direct in een query of API call zonder validatie. Klassieker dan ooit, maar nog steeds gangbaar bij AI-gegenereerde code.
Fix: gebruik parameterized queries (alle moderne ORMs doen dit by default). Valideer en sanitize alles wat van een gebruiker komt.
5. Geen rate limiting
Een API endpoint dat tien keer per seconde aangeroepen kan worden. Eén kwaadwillende gebruiker stuurt je AI bill of database de afgrond in.
Fix: rate limiting per IP of per user. Cloudflare doet dit gratis op de edge. Vercel en Railway hebben built-in opties.
OWASP Top 10 vertaald naar vibe coding
| OWASP risico | Vibe coding context |
|---|---|
| A01 Broken Access Control | Geen RLS, geen route auth |
| A02 Cryptographic Failures | Wachtwoorden in plain text, secrets in code |
| A03 Injection | SQL injection, prompt injection in AI features |
| A05 Security Misconfiguration | Default Supabase keys, debug mode aan in productie |
| A07 Identification Failures | Geen rate limit op login, geen 2FA optie |
Een security checklist voor live gaan
- Secrets allemaal in environment variables, niet in code
- RLS aan op elke database tabel met user data
- Auth check op elke server-side endpoint
- Input validatie op elk formulier (Zod, Joi, of vergelijkbaar)
- Rate limiting op auth en zware endpoints
- HTTPS overal (geen mixed content)
- CSP headers gezet
- Dependencies gescand op bekende CVE's (npm audit of Snyk)
- Backups van de database, automatisch
- Privacy policy aanwezig (GDPR vereiste in EU)
Waarom een mens hier nog steeds een voordeel heeft
Automatische security tools (npm audit, Snyk) vangen de bekende CVE's. Ze missen logische gaten: een endpoint die data van andere users teruggeeft is technisch geen "security vulnerability" voor een scanner, maar is wel een data leak.
Daarom werkt Ployed met human-in-the-loop deployment. Een engineer leest je code voor live, vangt deze categorie problemen, en deployt pas als het klopt. Lees meer over DevOps uitbesteden als startup of bekijk onze complete deployment gids.