TL;DR
Den kode, en AI skriver, kører som regel. Det, der fejler, er, hvem der kan nå dataene. I et audit af 200 udgivne apps lavet med vibe coding fra 2026 havde 91 % mindst én sårbarhed, og brudt adgangskontrol var den største gruppe. Jeg genskabte fem af adgangshullerne på en lokal Supabase: kun med den offentlige nøgle udleverede en tabel uden RLS, en altid-sand policy, et view og en lækket secret key hver især alle 3 af 3 rækker. Tjek din app for netop disse først.
Jeg er Denys, fullstack- og AI-ingeniør. Jeg retter apps bygget med Lovable, Bolt, Cursor eller Claude Code, og de fleste kører på Supabase. Denne artikel samler, hvad den publicerede forskning siger om sikkerhed ved vibe coding, og hvad jeg så, da jeg med vilje byggede de almindelige fejl om.
Hvad er sikkerhedsrisiciene ved vibe coding?
Hovedrisikoen er brudt adgangskontrol: data, som enhver besøgende kan læse eller ændre, fordi reglen, der skulle stoppe dem, mangler, er for løs eller bliver omgået. Injektion og svag godkendelse kommer derefter. Tre uafhængige studier peger i samme retning:
| Studie | Hvad blev testet | Hvad blev fundet |
|---|---|---|
| Deng, Fan og Meng, arXiv 2606.23130, juni 2026 | 200 udgivne apps bygget med Claude Code og Lovable, auditeret manuelt og med agenter | 182 af 200 apps (91 %) havde mindst én sårbarhed; 65,77 % af de 1.186 fund var Critical eller High; brudt adgangskontrol var den største kategori, i 64 % af apps |
| Escape, oktober 2025 | 5.600 offentlige apps fra Lovable, Base44, Create.xyz og andre, passiv scanning | Over 2.000 sårbarheder med stor effekt, over 400 afslørede hemmeligheder, 175 tilfælde af afslørede personoplysninger; hovedårsagen var fejlkonfigurerede tilladelser, især Supabase RLS |
| Veracode GenAI Code Security Report, 2025 og 2026 | 80 kodningsopgaver givet til over 100 modeller | Kun 55 % af opgaverne gav sikker kode i 2025; den gennemsnitlige beståelsesrate var 56 % i 2026, uændret på tværs af modelstørrelser og år |
Studierne måler forskellige ting, så procenterne lægger sig ikke sammen til ét tal. Det, de har tilfælles, er formen: koden virker, og hullerne sidder ved tillidsgrænsen.
Hvilke huller genskabte jeg?
Jeg oprettede én tabel, orders, med tre rækker fiktive kunder på en lokal Supabase (CLI 2.109.1, Postgres 17.6, PostgREST 14.14). Derefter kaldte jeg Data API’et, som en browser gør det, med den offentlige nøgle (publishable key), som hver eneste Supabase-frontend leverer, og ændrede én ting ad gangen.
| Opsætning | Hvad den offentlige nøgle fik | Hvorfor |
|---|---|---|
| Tabel uden RLS | Alle 3 rækker, og en indsættelse kom tilbage med 201 Created |
Standardrettighederne lader anon læse og skrive, og intet filtrerer rækker |
| RLS slået til, ingen policy | [], en tom liste |
RLS uden policy afviser alt for anon og authenticated |
Policy using (true) |
Alle 3 rækker | Policyen findes, så tabellen ser beskyttet ud, men den tillader hver række |
| View over den beskyttede tabel | Alle 3 rækker | Et view kører med ejerens rettigheder, medmindre det har security_invoker = true; med den giver det [] |
| Secret key i frontend-kode | Alle 3 rækker | Secret key svarer til service_role, som har BYPASSRLS |
Den anden række er det farlige øjeblik. RLS er slået til, og appen viser en tom liste, så den ser ødelagt ud. Den hurtigste prompt, der “retter” det, er en policy, der tillader alt, som er den tredje række. Den løkke, fejl og derefter en rettelse, der udvider adgangen, er det mønster, jeg oftest møder i apps lavet med vibe coding, og det er grunden til, at “RLS er slået til” alene siger så lidt.
Hvorfor fejler AI-skrevet kode på adgangskontrol?
En agent belønnes for kode, der kører. En tom liste eller et 401 ligner en fejl, og rettelsen, der får den til at forsvinde, er ofte den, der åbner adgangen. Studiet fra arXiv fører sine 1.186 fund tilbage til otte tilbagevendende fejlmønstre, grupperet som hukommelses-, mål- og vidensdefekter hos agenterne, og fandt, at bedre prompting mindskede antallet af huller, men ikke fjernede dem.
Den anden grund er arkitekturen. En Lovable- eller Bolt-app har som regel ingen egen backend: browseren taler direkte med databasen gennem Data API’et. Hver regel, der beskytter kundedata, skal ligge i Postgres som rettigheder, policies og funktioner, og intet af det kan ses i appens forhåndsvisning, hvor du er logget ind som ejer. Supabase ændrer en standard her: fra 30. oktober 2026 bliver nye tabeller i eksisterende projekter ikke længere automatisk givet adgang til Data API’et. På min stack svarede en tabel uden rettighed 42501 permission denied med et hint, der nævner den manglende GRANT. Det stopper den første række i tabellen ovenfor for nye tabeller, men ikke de fire andre og ikke tabeller, der allerede findes.
Hvad andet går galt uden for databasen?
De samme studier opregner risici, der intet har med RLS at gøre:
- Hemmeligheder i bundlen. Escape fandt over 400 afslørede hemmeligheder, blandt dem OpenAI-nøgler og admin-nøgler til betalinger. Alt, der sendes til browseren, er offentligt.
- Rutebeskyttelse kun i React. En side, der omdirigerer udloggede brugere, har stadig et API bag sig, som svarer til alle.
- Rate limits, der aldrig udløses. På et hostet Supabase-projekt, jeg undersøgte, blev en tæller i en edge functions hukommelse nulstillet ved hver anmodning. Det skrev jeg om i min sikkerhedstjekliste til Lovable-apps.
- Gamle biblioteker. Escape talte 254 sårbare forekomster af JavaScript-biblioteker i offentlige assets, ofte arvet fra skabeloner.
Hvordan tjekker du en app lavet med vibe coding?
- Åbn appen, åbn DevTools → Network, og find anmodninger til
/rest/v1/. Kopiér én som cURL, fjern headerenAuthorization, beholdapikey, og kør den. Hvis der kommer data tilbage, gør det det for alle. - Søg i den byggede JavaScript efter
sb_secret_ogservice_role. Et match er en nøgle, der skal roteres i dag. - Kør det gratis Supabase sikkerhedstjek. Det læser projektets katalog og markerer blandt sine 46 regler “RLS slået fra på eksponerede tabeller”, “Politikker, der tillader alle rækker”, “Views, der omgår RLS” og “Standardrettigheder, der åbner nye objekter for API’et”: de første fire rækker i tabellen ovenfor.
- Test med to brugere i to virksomheder, den ene test, en scanner ikke kan lave for dig. Hvordan jeg gør det, står i Lovable-tjeklisten, og sådan tester du Supabase RLS viser metoden på en produktionsapp med en tilladelsesskærm.
curl 'https://<project>.supabase.co/rest/v1/orders?select=*' \
-H 'apikey: <the publishable key from your page>'
Hvad dette ikke viser
Min genskabelse er én tabel på en lokal stack, bygget til at vise hver mekanisme, ikke en scanning af rigtige apps. Udbredelsestallene kommer fra de tre studier, hver med sin egen stikprøve og metode, linket ovenfor. Og et rent resultat på disse fem tjek gør ikke en app sikker: logikfejl, for eksempel en kontrol, der lader en manglende værdi slippe igennem, kræver egne tests. En af dem står i en NULL, der sprang en tilladelseskontrol over.
Har du bygget din app med et AI-værktøj?
Jeg udveksler gerne erfaringer om, hvad du bør tjekke først. Ingen salgstale.
Kontakt mig