← Tous les articles
Sécurité et gouvernance Développeurs Publié · · Par ObjectStack Team

Lovable est-il sûr pour la production ? Le problème du contrôle d'accès invisible

Lovable est puissant pour prototyper vite. En production, le vrai sujet est de pouvoir relire le contrôle d'accès : RLS, filtres frontend et scanners de sécurité ne sont pas équivalents.

Lovable est-il sûr pour la production ? Le problème du contrôle d'accès invisible
  • Lovable
  • Vibe Coding
  • Sécurité
  • Contrôle d'accès
  • AI-Native

TL;DR : Lovable est l’un des moyens les plus rapides pour un non-développeur de livrer une vraie app full-stack. Le danger est précis : le contrôle d’accès qui décide qui peut lire les données de vos utilisateurs est souvent généré sous forme de SQL RLS Supabase — par une IA, pour quelqu’un qui ne sait pas forcément lire le SQL. Un filtre frontend .eq('owner', user.id) qui fait que la démo se comporte correctement est une commodité de requête, pas une frontière de sécurité. « Ça marche » et « c’est sûr » sont des affirmations différentes, et la personne qui livre doit pouvoir les distinguer.

Laissez-moi vous montrer la forme exacte de la défaillance, parce que « le vibe coding est risqué » est inutile et que les détails sont tout.

Un fondateur décrit une app avec des comptes utilisateurs. Lovable la construit, branche Supabase et la livre. Chaque utilisateur ne voit que ses propres enregistrements. Le fondateur la teste avec deux comptes ; elle se comporte parfaitement. Dans la démo, elle est correcte.

Ouvrez maintenant l’onglet réseau du navigateur — ce qu’aucun non-développeur n’ouvre — et observez la requête que l’app fait réellement :

// le frontend « restreint » la requête à l'utilisateur actuel :
const { data } = await supabase
  .from('customers')
  .select('*')
  .eq('owner', user.id)   // ressemble à la frontière de sécurité. ce n'en est pas une.

Ce .eq('owner', user.id) est un filtre — un paramètre d’une requête. N’importe qui peut ouvrir l’onglet réseau, copier l’endpoint et le réémettre sans le filtre. Ce qui est censé l’empêcher d’obtenir les lignes de tout le monde, c’est la politique de sécurité au niveau des lignes sur la table. Voici ce que Lovable génère couramment :

-- la politique RLS censée être la frontière :
create policy "Enable read access for all users"
  on public.customers for select
  using (true);          -- ← vaut true pour chaque ligne, chaque appelant

using (true) signifie : tout appelant authentifié peut lire toutes les lignes. La politique existe. Elle est active. Et elle ne protège rien. L’app est sûre dans exactement une configuration — celle que le frontend se trouve demander — et grande ouverte à l’instant où quelqu’un demande autre chose. Ce n’est pas une subtilité académique ; cette classe d’erreur a déjà produit des incidents publics.

Un filtre n’est pas une frontière

C’est tout le concept, et il vaut la peine de le nommer parce qu’une fois que vous le voyez, vous ne pouvez plus le dé-voir : un filtre est une commodité de requête ; une frontière est appliquée sur le serveur quelle que soit la requête. La démo marche grâce au filtre. Les données ne sont sûres que s’il y a une frontière. Les deux sont indiscernables de l’extérieur — toutes deux font que deux comptes de test voient ce qu’il faut — et c’est précisément pour cela qu’un non-développeur ne peut pas distinguer une app sûre d’une app exposée en l’utilisant.

La personne que Lovable habilite à construire l’app est, par la conception même du produit, la personne la moins équipée pour lire la différence entre using (true) et un vrai using (auth.uid() = owner). La capacité et la compréhension ont été séparées. Cette séparation est la magie du produit et sa responsabilité d’un même geste.

Démonter la réfutation évidente : « Lovable a ajouté un scanner de sécurité »

Au crédit de Lovable : cette critique a porté et ils ont répondu — un scanner de sécurité, une offre enterprise avec SSO et journaux d’audit. La question juste est donc : est-ce que cela ne clôt pas le sujet ?

Regardez ce que le scanner peut et ne peut pas vérifier. D’après le comportement rapporté, il vérifie qu’une politique RLS existe sur une table — et using (true) est une politique qui existe. Il valide « une politique est présente » tout en n’appliquant rien. Vérifier la présence est mécanique ; vérifier l’efficacité — cette politique contraint-elle réellement qui lit quoi — exige de comprendre le modèle de données et de raisonner sur chaque chemin d’accès, ce qui est exactement le jugement d’expert que l’outil existe pour permettre aux utilisateurs de sauter. Le scanner ne peut pas fournir la compréhension que le produit a retirée ; il peut seulement confirmer que la compréhension a été retirée d’une manière sûre-en-apparence.

Et les contrôles enterprise — SSO, journaux d’audit de l’organisation — régissent comment les gens se connectent à Lovable, pas quel RLS l’IA a écrit dans votre app. Ils sont réels et bons et orthogonaux. La faille n’est pas la posture enterprise de Lovable. C’est que la logique d’accès propre à chaque app que l’IA génère est illisible pour la seule personne qui en est responsable.

Le chiffre utile : l’asymétrie de vérification

Voici le chiffre qui rend le motif inévitable plutôt que malchanceux. Comparez deux coûts :

  • Coût pour construire l’app : une phrase. Effectivement nul, par conception — c’est tout l’argumentaire.
  • Coût pour vérifier qu’elle est sûre : lire le RLS généré pour chaque table, raisonner sur chaque chemin d’API, distinguer les filtres des frontières. Des heures d’expert, et une compétence que le constructeur n’a pas.

Quand le coût de construction s’effondre presque à zéro mais que le coût de vérification reste à des heures d’expert, le comportement rationnel d’un non-expert est de sauter la vérification — parce qu’il ne peut pas la faire et que l’app a l’air terminée. Ce n’est pas un problème propre à un logo. C’est ce que l’asymétrie de vérification produit avec n’importe quel outil qui laisse des non-experts générer un contrôle d’accès qu’ils ne savent pas lire.

Là où Lovable a exactement raison — et la réserve honnête

Pour un prototype, une landing page, un projet de hackathon, un outil interne jetable, une démo de levée de fonds — partout où aucune donnée d’une personne réelle ne se trouve derrière l’app — Lovable est excellent et presque certainement plus rapide que tout ce qui est plus discipliné, nous compris. L’asymétrie de vérification ne coûte rien quand il n’y a rien à exposer. Utilisez-le, et profitez-en.

Et la réserve honnête qui empêche ceci d’être un règlement de comptes : c’est structurel, pas un défaut de Lovable. Tout outil qui effondre le coût de construction pour les non-experts tout en laissant la vérification à un coût d’expert hérite de la même asymétrie — et Lovable essaie activement de la réduire. Le propos n’est pas « Lovable est mauvais ». C’est que pour des données de production, « le constructeur ne sait pas lire le contrôle d’accès » est disqualifiant peu importe le logo sur le constructeur.

La ligne est nette : à l’instant où les données de personnes réelles vivent derrière — clients, patients, employés — « ça marche » cesse d’être une preuve de quoi que ce soit, et « je ne vois pas la frontière » cesse d’être une commodité pour devenir le risque.

Un test que vous pouvez faire en trente secondes

Oubliez la liste de fonctionnalités. Demandez à celui qui l’a livrée :

« Ouvre l’onglet réseau, prends la requête de données, retire le filtre et envoie-la. Récupères-tu seulement tes lignes — ou celles de tout le monde ? »

S’il ne peut pas faire ce test, ou ne le comprend pas, ou si la réponse est « celles de tout le monde », l’app est un beau prototype et pas un système de production — peu importe à quel point elle a l’air soignée ou qu’un scanner lui ait donné une coche.

La position d’ObjectStack

ObjectStack inverse la séparation qui cause les fuites. Le contrôle d’accès n’est pas du SQL généré que le constructeur ne sait pas lire ; ce sont des métadonnées déclarées et lisiblesread: owner == current_user comme propriété de l’objet — et c’est une frontière que le runtime applique côté serveur, de sorte que retirer un filtre frontend ne change rien. Quand l’IA propose un changement sur qui-peut-lire-quoi, cela apparaît comme un diff qu’un non-expert peut réellement approuver (« ceci rend customers lisible par tout le monde — confirmer ? »), jamais comme un silencieux using (true) qu’il aurait fallu lire du SQL pour attraper. Et parce que c’est auto-hébergeable et que cela repose sur des systèmes que vous exécutez déjà, les données sensibles n’atterrissent pas discrètement quelque part que vous ne pouvez pas inspecter.

Nous ne battrons pas Lovable sur le temps-jusqu’à-la-première-démo, et pour des prototypes nous n’essaierions pas. L’affirmation est celle qui compte à l’instant où de vraies données sont en jeu : la sécurité d’une app construite par IA doit être visible pour la personne qui en répond — parce qu’une app dont vous ne pouvez pas voir la frontière n’est pas sûre, elle est seulement non testée en public.