AI-appbuilders hebben miljoenen mensen zonder programmeerachtergrond tot softwaremakers gemaakt. Lovable alleen al meldt zo’n 8 miljoen gebruikers en meer dan 200.000 nieuwe projecten per dag (TechCrunch). Veel van die apps bevatten inmiddels echte klantgegevens, verwerken echte betalingen en sturen echte processen aan – ook in het mkb, waar de salesmanager “even snel” een offertetool in elkaar heeft gezet.
De ongemakkelijke waarheid: een app die in de demo perfect werkt, kan elke ingelogde gebruiker de gegevens van alle anderen laten zien – door één getal in een verzoek te veranderen. Generators optimaliseren voor wat je op het scherm ziet. Beveiliging is onzichtbaar, tot het misgaat.
Deze gids geeft je een praktische audit-checklist voor apps die zijn gebouwd met Lovable, Bolt, Replit, Cursor en vergelijkbare tools. Je leest waar zulke apps meestal breken, hoe een korte reddingsaudit verloopt en hoe je kiest tussen repareren, refactoren en opnieuw bouwen.
De omvang van het probleem in cijfers
Het bewijs uit 2025 en 2026 is eenduidig:
- 5.600 openbare apps gescand, meer dan 2.000 ernstige kwetsbaarheden. Securitybedrijf Escape vond daarnaast 400 blootgestelde secrets en 175 gevallen van gelekte persoonsgegevens (SoftwareSeni).
- CVE-2025-48757: bij 170 van de 1.645 gecontroleerde Lovable-apps lagen gegevens open omdat Row Level Security was uitgeschakeld (Cloud Security Alliance, The Next Web).
- Ook de platforms zelf zijn niet immuun. In april 2026 maakte een BOLA-lek in Lovable zelf de code en databasegegevens van andere gebruikers 48 dagen lang toegankelijk (The Next Web).
- 406 miljoen records lekten uit de app Chat & Ask AI door een Firebase-regel die simpelweg alles toestond (CSA).
- Ongeveer 55% van de AI-gegenereerde code is veilig volgens tests van Veracode, en dat percentage is ondanks betere modellen niet gestegen (SoftwareSeni).
- 19,7% van de pakketten die modellen voorstellen, bestaat niet – een cadeautje voor aanvallers die precies die namen registreren, ook wel slopsquatting genoemd (CSA).
Dat betekent niet dat de tools waardeloos zijn. Het betekent dat een gegenereerde app een eerste versie is die nog nooit een securityspecialist heeft gezien.
Waar vibe-coded apps breken: vijf terugkerende zwakke plekken
1. Toegangsregels in de database
Veel builders combineren een frontend met Supabase of Firebase. De browser praat met een openbare sleutel rechtstreeks met de database. Dat is zo bedoeld – zolang toegangsregels bepalen wie welke rij mag lezen en schrijven. In Supabase heet dat Postgres Row Level Security (RLS), in Firebase zijn het security rules. Staat RLS uit op een tabel, of zegt een regel in feite “lezen en schrijven: altijd toegestaan”, dan is die tabel openbaar voor iedereen die de browserconsole opent.
Typische bevindingen: RLS aan op de eerste tabellen maar niet op tabellen die later zijn toegevoegd; policies die alleen controleren of iemand “ingelogd” is in plaats van “eigenaar van deze rij”; storage-buckets met geüploade documenten die openbaar staan; de service-role-sleutel, die alle regels omzeilt, meegeleverd aan de browser.
2. Autorisatie in de API
Authenticatie beantwoordt “wie ben je?”. Autorisatie beantwoordt “mag jij aan dit record komen?”. Gegenereerde code doet vaak het eerste en vergeet het tweede. Het resultaat heet broken object level authorization (BOLA): verander /facturen/1042 in /facturen/1043 en je ziet de factuur van een andere klant. Niet voor niets staat BOLA bovenaan de OWASP API Security Top 10.
Een tweede patroon is beveiliging door verstoppen: de beheerknop is onzichtbaar voor gewone gebruikers, maar het beheer-endpoint erachter controleert de rol niet.
3. Secrets op de verkeerde plek
API-sleutels van modelaanbieders, geheime betaalsleutels en databasegegevens belanden in de frontend-bundle, in ingecheckte omgevingsbestanden of in de systeemprompt van een AI-functie. De sleutel verwijderen uit de laatste commit is niet genoeg: in de git-geschiedenis blijft hij staan tot je hem roteert.
4. Afhankelijkheden die niemand heeft gekozen
Gegenereerde projecten halen tientallen pakketten binnen. Sommige zijn verouderd en hebben bekende kwetsbaarheden, sommige zijn – zie die 19,7% – door het model verzonnen en inmiddels misschien door iemand anders geregistreerd. Zonder lockfile en controle van afhankelijkheden weet niemand wat er in productie echt draait.
5. Onbeveiligde AI-endpoints
Roept je app een taalmodel aan, dan komen er twee nieuwe risico’s bij. Prompt injection: tekst van gebruikers of geüploade documenten bevatten instructies die de jouwe overschrijven. Kostenmisbruik: een endpoint zonder rate limits of budgetlimieten laat iedereen je modelrekening opdrijven. Hoe je je daartegen verdedigt, lees je in prompt injection en de beveiliging van agents.
Een zelftest van 30 minuten voordat je iemand inschakelt
De gevaarlijkste problemen kun je bij je eigen app zelf opsporen:
- Open het dashboard van je database (Supabase, Firebase of vergelijkbaar) en zet alle tabellen en storage-buckets op een rij. Noteer waar toegangsregels aanstaan. Elke tabel zonder regels is een rode vlag.
- Doorzoek je gepubliceerde frontend op secrets. Open de live site, bekijk de JavaScript-bestanden in de ontwikkelaarstools van je browser en zoek naar tekenreeksen als
sk_,secret,service_roleof het sleutelprefix van je modelaanbieder. Een openbare “anon”- of “publishable”-sleutel is normaal, een geheime sleutel niet. - Maak twee testaccounts aan. Log in met het eerste, maak een record aan en kopieer het ID uit de adresbalk of het netwerktabblad. Log in met het tweede en open dat ID. Laadt het, dan heb je een BOLA-probleem.
- Probeer beheerpagina’s als gewone gebruiker door de URL direct in te typen. Laadt er iets, dan is de bescherming cosmetisch.
- Controleer wie geüploade bestanden kan zien. Open de link naar een document in een privévenster. Opent het zonder in te loggen, dan is de bucket openbaar.
- Kijk op de gebruikspagina van je modelaanbieder. Onverklaarbare pieken kunnen betekenen dat iemand je AI-endpoint heeft gevonden.
Faalt een van deze tests, stop dan met nieuwe functies en repareer eerst de basis. Slagen ze allemaal, dan heb je nog steeds de volledige checklist nodig: deze zes tests vangen de luidste problemen, niet alle.
De audit-checklist: 24 punten
Gebruik de tabel als werklijst. De ernst geeft de typische impact aan als een controle faalt.
| # | Gebied | Wat controleren | Ernst |
|---|---|---|---|
| 1 | Database | RLS (of vergelijkbare regels) aan op elke tabel, ook op later toegevoegde | Kritiek |
| 2 | Database | Policies controleren eigenaarschap of rol, niet alleen “ingelogd” | Kritiek |
| 3 | Database | Aparte policies voor lezen, toevoegen, wijzigen en verwijderen | Hoog |
| 4 | Storage | Buckets met gebruikersbestanden privé; links ondertekend en tijdelijk | Kritiek |
| 5 | Sleutels | Service-role- of beheersleutels uitsluitend op de server | Kritiek |
| 6 | Autorisatie | Elke API-route en serverfunctie controleert toegang tot precies dit record | Kritiek |
| 7 | Autorisatie | Beheerfuncties beveiligd op de server, niet alleen verborgen in de interface | Kritiek |
| 8 | Authenticatie | Wachtwoordherstel, e-mailwijziging en uitnodigingen niet te kapen | Hoog |
| 9 | Authenticatie | Sessies verlopen; tokens niet onnodig leesbaar voor scripts opgeslagen | Middel |
| 10 | Secrets | Frontend-bundle zonder geheime sleutels (gebouwde JavaScript doorzoeken) | Kritiek |
| 11 | Secrets | Git-geschiedenis gescand; elke gelekte sleutel geroteerd, niet alleen verwijderd | Kritiek |
| 12 | Secrets | Systeemprompts zonder sleutels, interne URL’s of vertrouwelijke regels | Hoog |
| 13 | Afhankelijkheden | Elk pakket bestaat, wordt onderhouden en staat vast in een lockfile | Hoog |
| 14 | Afhankelijkheden | Controle op bekende kwetsbaarheden geslaagd; SBOM aanwezig | Middel |
| 15 | Invoer | Alle invoer gevalideerd op de server; uploads gecontroleerd op type en grootte | Hoog |
| 16 | AI | Modeloutput als onbetrouwbaar behandeld: nooit uitgevoerd, nooit direct in queries | Hoog |
| 17 | AI | Rate limits en maandelijkse budgetlimieten op elk endpoint dat een model aanroept | Hoog |
| 18 | AI | Opgehaalde documenten en gebruikersinhoud gescheiden van instructies; injectietests uitgevoerd | Hoog |
| 19 | Web | Alleen HTTPS, securityheaders ingesteld, CORS beperkt tot je eigen domeinen | Middel |
| 20 | Beheer | Back-ups aanwezig en een herstel daadwerkelijk getest | Hoog |
| 21 | Beheer | Logs leggen securitygebeurtenissen vast, maar geen wachtwoorden, tokens of onnodige persoonsgegevens | Middel |
| 22 | Beheer | Foutmonitoring en alarmen komen bij een mens terecht | Middel |
| 23 | Privacy | Overzicht van persoonsgegevens: waar ze staan en welke leveranciers ze verwerken (met verwerkersovereenkomst) | Hoog |
| 24 | Privacy | Gebruikers kunnen hun gegevens exporteren en verwijderen; verwijderen haalt ze echt weg | Middel |
De Cloud Security Alliance adviseert voor elke AI-gegenereerde codebase een vergelijkbaar minimum: statische codeanalyse, controle van afhankelijkheden en secret scanning als verplichte CI-stappen; een audit van de databaseregels; een aparte menselijke review van authenticatie-, API- en datacode; een SBOM; en controle of elk voorgesteld pakket echt bestaat.
Zo verloopt een reddingsaudit van 3–5 dagen
Dag 1: toestemming, toegang en inventarisatie
Eerst de juridische basis: een schriftelijke opdracht en geverifieerd eigendom van de app, bijvoorbeeld via een DNS-record of een metatag op het domein. Dan leestoegang tot repository, database, hosting en alle externe diensten. De uitkomst is een inventarisatie: componenten, gegevensopslag, leveranciers, gebruikersrollen en de data die elke rol raakt.
Dag 2: automatische scans
Statische codeanalyse, een controle van afhankelijkheden, een secret-scan van de bundle en van de volledige git-geschiedenis, en een export van alle databasepolicies en storage-regels. Automatische tools vinden het voor de hand liggende snel – en leveren valse meldingen op die een mens moet beoordelen.
Dag 3 (en 4 bij grotere apps): handmatige tests
Hier komen de kritieke bevindingen meestal vandaan. Met twee testaccounts probeert de auditor via elk endpoint en elke tabel de gegevens van het andere account te lezen en te wijzigen. Beheerfuncties worden rechtstreeks aangeroepen, AI-endpoints worden getest met injectiepayloads en hoge aantallen verzoeken.
Laatste dag: rapport en kritieke reparaties
Elke bevinding krijgt een ernst, een bewijs (verzoek en antwoord), de zakelijke impact in gewone taal en een oplossing. Kritieke zaken – openbare tabellen, gelekte sleutels – worden vaak dezelfde dag opgelost, sleutels worden geroteerd en de tests opnieuw gedraaid. Het rapport eindigt met een herstelplan en een inschatting voor de rest.
Repareren, refactoren of opnieuw bouwen?
| Wat de audit laat zien | Besluit | Typische inspanning |
|---|---|---|
| Degelijk datamodel; problemen zijn ontbrekende regels, gelekte sleutels, onbeveiligde routes | Ter plekke repareren | Dagen |
| Datamodel bruikbaar, maar bedrijfslogica en controles zitten in de browser | Refactoren: een echte server- of API-laag toevoegen | Weken |
| Verkeerd datamodel, geen tests, dezelfde logica over veel schermen gekopieerd, sterke platform-lock-in | Kern opnieuw bouwen en data migreren | Weken tot maanden |
Aanbieders noemen voor reddingsprojecten bedragen van $ 50.000–500.000 per app, maar dat is een ongecontroleerde marge uit marketingmateriaal (Creatr). De echte kostendrijver is hoeveel er aan het datamodel moet veranderen. Gartner verwacht volgens berichtgeving dat 75% van de bedrijven te maken krijgt met gemiddelde of hoge technische schuld door AI-gegenereerde code (Reptile.haus). Hoe eerder de audit, hoe goedkoper de reparatie.
Ga je nog bouwen in plaats van repareren? Een gestructureerde sprint voorkomt de meeste van deze problemen vanaf het begin; zie een MVP in 14 dagen.
Als je een datalek vindt
Behandel een openstaande tabel of gelekte sleutel als incident, niet als to-do:
- Indammen: toegangsregels aanzetten, sleutels intrekken en roteren, het betreffende endpoint uitschakelen.
- Bewijs veiligstellen: logs bewaren voordat er iets wordt overschreven.
- Beoordelen: welke gegevens, hoeveel mensen, hoe lang, en heeft iemand er echt bij gekund?
- Melden als dat moet: onder artikel 33 van de AVG moet een inbreuk in verband met persoonsgegevens binnen 72 uur nadat je ervan op de hoogte bent gemeld worden bij de toezichthouder – in Nederland de Autoriteit Persoonsgegevens – tenzij het waarschijnlijk geen risico voor de betrokkenen oplevert. De AI-specifieke kanten behandelen we in de AVG voor AI-chatbots.
Veelgemaakte fouten
- Verstoppen in plaats van beveiligen. Een onzichtbare knop is geen toegangscontrole.
- Alleen de bekende tabellen repareren. Tabellen die volgende maand worden aangemaakt, gaan zonder RLS live als CI daar niet op controleert.
- Sleutels verwijderen in plaats van roteren. Een sleutel in de git-geschiedenis is nog steeds een gelekte sleutel.
- Op één scanner vertrouwen. Ingebouwde platformcontroles zijn nuttig, maar testen niet of gebruiker A de gegevens van gebruiker B kan lezen.
- Dezelfde tool zijn eigen werk laten controleren. AI-reviews helpen, maar kritieke paden vragen om een mens die de bedrijfsregels begrijpt.
- Testen zonder toestemming. Ook goedbedoeld scannen van andermans app kan strafbaar zijn.
- De audit als eenmalige actie zien. Elke functie die volgende week wordt gegenereerd, kan dezelfde problemen opnieuw introduceren.
Conclusie
Vibe coding is een legitieme manier om snel een product bij gebruikers te krijgen. De risico’s zijn goed gedocumenteerd en opvallend voorspelbaar: toegangsregels, autorisatie, secrets, afhankelijkheden en AI-endpoints. Een gerichte audit vindt de kritieke problemen in een paar dagen, en een handvol CI-controles voorkomt dat ze terugkomen. Het doorlopende toezicht daarna hoort thuis in AI Ops, niet in goede voornemens.
Bevat je app al klantgegevens, dan wil je weten waar je staat. Ons Build-team voert reddingsaudits uit en de reparaties die daarop volgen. Plan een gratis auditgesprek van 15 minuten en we vertellen je welke controles je als eerste moet doen.