← Stack-gidsen

Lovable

Beveiliging en zichtbaarheid voor je Lovable-app

Met Lovable lanceer je in minuten een prachtige app, maar vaak als een SPA die AI niet ziet en met sleutels die in de frontend belanden. Scan je site en ontdek wat er ontbreekt voordat je hem deelt.

Typische risico's bij Lovable

Onzichtbaar voor AI

Als je content pas verschijnt nadat JavaScript draait, zien AI-crawlers een lege pagina en kunnen ze je niet citeren. Het is de meest voorkomende AEO-fout in gegenereerde apps.

API-sleutels in de browser

Bij het verbinden van diensten zet de AI de sleutel vaak direct in de frontend, waar hij voor iedereen zichtbaar is. Sleutels horen op de server te staan.

Ontbrekende headers en basis-SEO

Gegenereerde apps worden meestal geleverd zonder beveiligingsheaders of SEO-metatags. Dit zijn snelle fixes die een groot verschil maken.

"Lovable-beveiliging" zijn twee dingen die je beter uit elkaar houdt. Het eerste is het Lovable-project zelf: wat je in de chat plakt, waar het geheimen opslaat, wie je project kan zien en waar de app uiteindelijk gedeployed wordt. Het tweede is de code die Lovable genereert, een React-SPA op Supabase die altijd dezelfde vijf of zes fouten meebrengt. Deze gids behandelt beide, met een instructieblok voor de Knowledge-sectie van je project, een reviewprompt vóór het publiceren en de manier om het resultaat van buitenaf te controleren.

Deel 1: je Lovable-project beveiligen

Wat je in de chat plakt, blijft daar

De projectchat is de geschiedenis van je app: elke prompt, elke sleutel die je "om het werkend te krijgen" plakte en elk antwoord. Komt een geheime sleutel via de chat binnen, dan schrijft het model hem vaak rechtstreeks in de frontendcode, en van daaruit reist hij in de bundle naar elke bezoeker. De regel is simpel: sleutels komen nooit via de chat binnen. Wanneer Lovable je om een geheim vraagt om een dienst te koppelen, gebruik dan het secrets-veld dat het aanbiedt; dat slaat het op als variabele van de Supabase Edge Functions, aan de serverkant, en de gegenereerde code leest het met Deno.env.get.

Geheimen: server ja, browser nee

Lovable kan twee dingen met een integratie: hem aanroepen vanuit de browser of vanuit een Edge Function. Het eerste is juist voor publieke sleutels (de anon van Supabase, de publishable van Stripe, een project-ID). Het tweede is de enige optie voor geheime sleutels (OpenAI, Resend, de secret van Stripe, de service_role). Vraag je om een functie en roept het resultaat de dienst aan vanuit een React-component met de sleutel erin, vraag dan expliciet om hem naar een Edge Function te verplaatsen. Meer in geheimen die je app in de browser lekt.

Zichtbaarheid van project en code

Een publiek project op Lovable stelt de code en de promptgeschiedenis bloot aan iedereen met de link, inclusief elke sleutel die je ooit plakte. Controleer de zichtbaarheid in de projectinstellingen en, als je GitHub-synchronisatie hebt ingeschakeld, of de repository privé is. Heeft een sleutel ooit in een publiek project of repository gestaan, beschouw hem dan als gecompromitteerd en roteer hem.

Waar de gepubliceerde app leeft

Lovable publiceert op een .lovable.app-subdomein of op je eigen domein. Die hosting laat je geen beveiligingsheaders of eigen redirects configureren. Voor veel apps is dat genoeg; heb je Content-Security-Policy, HSTS of cacheregels nodig, exporteer dan naar GitHub en deploy op Vercel of Netlify met hun configuratiebestand. Houd er ook rekening mee dat de preview-URL van elke versie bereikbaar is voor wie hem heeft.

Supabase is van jou, niet van Lovable

Wanneer je Supabase koppelt (of de beheerde backend van Lovable gebruikt, wat onderliggend Supabase is), maakt Lovable tabellen, policies en functies voor je aan. Maar RLS, buckets en Auth-instellingen blijven jouw verantwoordelijkheid. Lovable voegde na CVE-2025-48757 een beveiligingscontrole vóór het publiceren toe; zie die als een eerste filter, niet als garantie, en loop de beveiligingsgids voor Supabase door, met drie SQL-query's om het project in een minuut door te lichten.

Deel 2: de fouten die Lovable in je code stopt

  • Tabellen zonder RLS of met using (true)-policies. De oorsprong van de CVE en de ernstigste fout. Iedereen met de anon-sleutel leest en schrijft je data.
  • Rechtencontroles alleen in de frontend. Een /admin-route die alleen de knop verbergt als de gebruiker geen admin is. De server (RLS of de Edge Function) moet het ook controleren, want de API kan worden aangeroepen zonder de interface.
  • Edge Functions zonder authenticatie of limiet. Het template antwoordt iedereen, met Access-Control-Allow-Origin: *, en als het OpenAI aanroept of e-mails verstuurt, kan iedereen je quotum opmaken. Eis het JWT van de gebruiker, beperk de origin en zet een plafond op verzoeken per gebruiker.
  • Publieke buckets voor gebruikersbestanden. Lovable maakt de bucket publiek zodat afbeeldingen "te zien zijn". Voor privédocumenten: private bucket en ondertekende URL's.
  • Onzichtbaar voor AI en zoekmachines. De app is een Vite-SPA: de HTML komt leeg aan en de bots van ChatGPT of Perplexity zien niets. Als de landingspagina en blog ertoe doen, scheid ze dan van de app. Details in waarom met AI gebouwde apps onzichtbaar zijn voor AI.
  • Geen beveiligingsheaders of metadata. Geen CSP, geen HSTS, geen X-Frame-Options, en de titel is die van het template. Het eerste vereist een deployment buiten lovable.app; het tweede los je op met één prompt.
  • Validatie alleen in het formulier. Het veld heeft maxLength maar de Edge Function of de tabel accepteert wat er binnenkomt. Valideer ook op de server en in de databaseconstraints.

Een blok voor de Knowledge-sectie van je project

In de projectinstellingen heeft Lovable een kennissectie die het model bij elk verzoek leest. Plak dit zodat de regels vanaf de eerste prompt gelden:

Beveiligingsregels van dit project:
- Elke nieuwe tabel heeft RLS ingeschakeld en één expliciete policy per bewerking. Gebruik nooit using (true) of with check (true), behalve op tabellen met publieke alleen-lezen inhoud, en zeg het me als je dat doet.
- Zet nooit geheime sleutels in frontendcode. Integraties met geheime sleutels gaan in een Edge Function die het geheim leest met Deno.env.get.
- Elke Edge Function verifieert het JWT van de gebruiker tenzij ik anders zeg, beperkt Access-Control-Allow-Origin tot ons domein en valideert de invoer.
- Adminrechten worden gecontroleerd in RLS of op de server, nooit alleen in de frontend.
- Door gebruikers geüploade bestanden gaan naar private buckets met policies en ondertekende URL's.
- De kolommen role, is_admin, plan en credits zijn niet door de gebruiker te bewerken.
- Zet een echte titel, metabeschrijving en Open Graph-tags in index.html.

Een reviewprompt vóór het publiceren

Beoordeel de beveiliging van dit project en verander nog niets. Antwoord met een lijst:
1. Tabellen zonder RLS en policies met using (true) of with check (true).
2. Sleutels of tokens in de frontendcode, met bestand en regel.
3. Edge Functions die het JWT niet verifiëren, antwoorden met Access-Control-Allow-Origin: * of de invoer niet valideren.
4. Adminroutes of -acties die alleen in de frontend beschermd zijn.
5. Publieke buckets met gebruikersbestanden.
6. Privilegekolommen die een gebruiker kan wijzigen.
7. Metadata in index.html die nog van het template zijn.
Stel voor elk punt de exacte wijziging voor en wacht op mijn bevestiging.

Controleer het resultaat van buitenaf

Open je gepubliceerde app in een incognitovenster, rechtermuisknop, "Paginabron weergeven", en zoek naar service_role, sk_live, sk- en Bearer in de JavaScript-bestanden die hij laadt. Test daarna de Supabase-API zonder sessie:

curl -s "https://JOUW_PROJECT.supabase.co/rest/v1/profiles?select=*" -H "apikey: JOUW_ANON_KEY" -H "Authorization: Bearer JOUW_ANON_KEY"

Komen er rijen terug, dan staat die tabel open. Scanaris doet dit en zo'n veertig andere controles in 30 seconden: het detecteert dat de app met Lovable is gebouwd, test de Supabase-tabellen zonder sessie, zoekt geheimen in de bundle, controleert headers, cookies, CORS en blootgestelde bestanden, en checkt of je inhoud leesbaar is zonder JavaScript. Voor elke fout krijg je een fix prompt om in de Lovable-chat te plakken met de exacte wijziging, en het kan elke dag opnieuw scannen, want een hergeneratie van code kan een al opgeloste fout terugbrengen.

Veelgestelde vragen

Heeft Lovable het RLS-probleem al opgelost?

Lovable voegde een beveiligingscontrole vóór het publiceren toe en verbeterde de templates, maar het model genereert nog steeds open policies wanneer een query faalt. RLS blijft jouw verantwoordelijkheid: gebruik de query's uit de Supabase-gids.

Kan ik beveiligingsheaders zetten op een app die op lovable.app wordt gehost?

Niet vanuit Lovable. Heb je ze nodig, synchroniseer dan met GitHub en deploy op Vercel of Netlify, waar ze met een bestand worden geconfigureerd. De app blijft bewerkt worden in Lovable.

Wat doe ik als ik een geheime sleutel in de chat heb geplakt?

Roteer hem bij de brondienst, ook als hij niet meer in de code staat: de chatgeschiedenis en eerdere bundles bewaren hem. Voeg hem daarna toe via het secrets-veld en vraag het model de integratie naar een Edge Function te verplaatsen.

Gerelateerde checks

Doorstaat je Lovable-app deze checks?

Scan hem gratis en krijg een fixprompt voor elk probleem dat we vinden.

Mijn site gratis scannen