Le blog

Code généré

Le scan est vert. Le client A peut-il lire la facture du client B ?

Le contrôle automatique d’une plateforme lit la configuration et vérifie que des règles d’accès existent. Il ne sait pas qui doit voir quelle facture. Ce test-là se fait avec deux comptes, une requête modifiée et une règle écrite en une phrase.

Portrait de Raphaël Prasquier

Raphaël Prasquier

Infrastructure & sécurité applicative

Publié
Lecture
8 min
Deux boîtes aux lettres d’immeuble identiques sur un fond papier, l’une marquée d’une pastille indigo, l’autre d’une pastille menthe ; une enveloppe indigo dépasse de la fente de la boîte menthe.
Illustration conçue avec l’IA

La plateforme affiche un contrôle de sécurité réussi. L’application est en production, des clients paient, leurs factures se téléchargent. Une question reste pourtant hors du tableau vert : si le client B remplace, dans sa requête, l’identifiant de sa facture par celui d’une facture du client A, que renvoie le serveur ?

Ce n’est pas une affaire d’outil. C’est une règle métier, « un client ne voit que ses propres factures », que personne n’a écrite ailleurs que dans sa tête. Voici pourquoi le contrôle automatique ne peut pas la deviner, où elle casse dans une application construite sur Supabase, et comment la vérifier avec deux comptes de test.

Ce que le contrôle vert a vraiment vérifié

Prenons Lovable, dont la documentation est précise. Son analyse rapide « déroule un ensemble fixe de contrôles en quelques secondes » et se lance à chaque publication : tables sans sécurité au niveau des lignes, règles d’accès qui laissent passer tout le monde, dépendances npm vulnérables, serveurs MCP ouverts sans authentification[1]. Une analyse approfondie relit le code de l’application, permissions comprises ; elle ne se lance pas d’elle-même[1]. La page prévient enfin que ces outils « ne peuvent pas garantir une sécurité complète »[1].

Ce contrôle a progressé. En mars 2025, le chercheur Matt Palmer avait montré que des sites générés par Lovable laissaient lire leurs tables sans authentification. Il relevait que le scanner livré ensuite avec Lovable 2.0 vérifiait seulement qu’une politique RLS existait, « pas sa justesse ni son accord avec la logique de l’application »[2]. La faille porte l’identifiant CVE-2025-48757 et une note de gravité de 9,3 sur 10 ; Lovable la conteste, au motif que chaque client répond de la protection des données de son application[3].

Sur ce point, l’éditeur est cohérent. Le 21 octobre 2026, il a écrit ce qui reste à votre charge : « testez avec des comptes séparés et des rôles différents », puis cette question, presque celle de notre titre : un client peut-il lire les enregistrements d’un autre client[4] ? Son rapport SOC 2 évalue Lovable comme fournisseur et « ne constitue pas un audit de votre entreprise ou de votre application »[4]. Le tableau vert dit que la plateforme a relu sa liste. Il ne dit pas que votre règle est respectée.

La clé est publique, la règle n’est écrite nulle part

Dans une application construite sur Supabase, le navigateur parle directement à la base, avec une clé inscrite dans le code de la page. C’est voulu. La documentation la dit « sûre à exposer » et précise qu’elle n’atteint que « ce que la sécurité au niveau des lignes autorise »[5]. La clé n’est donc pas le problème : la cacher ou la remplacer ne protège aucune facture.

Tout se joue donc dans le texte des politiques, et la même politique peut être juste ici, fausse là. « Tout utilisateur connecté lit toutes les factures » convient à un outil interne où une seule équipe partage ses données. Dans un logiciel vendu à plusieurs entreprises, c’est exactement la fuite du client A vers le client B. Rien dans la configuration ne dit laquelle des deux applications vous avez construite.

Trois colonnes montrent la même requête, envoyée avec la clé publique par le client B connecté. Première colonne, RLS désactivée et droits SQL de lecture accordés : la table renvoie les factures de tous les clients, et un contrôle automatique le signale. Deuxième colonne, avec une politique qui vérifie seulement que l’utilisateur est connecté : la table renvoie encore les factures de tous les clients, alors que la configuration paraît en ordre. Troisième colonne, avec une politique qui compare le client propriétaire de la ligne au client connecté : la table ne renvoie que les factures du client B.
Schéma 1 Même clé, même requête : seul le contrôle d’accès de la base change la réponse. La deuxième colonne passe pour la troisième tant que personne n’a testé avec un second compte.

Un contrôle automatique repère sans peine la première colonne, et souvent la règle qui ouvre tout à tous. Entre « tout utilisateur connecté » et « le propriétaire de la ligne », il lui faudrait connaître votre intention. Or elle n’est écrite nulle part : elle vit dans la tête de l’équipe, dans un ticket, parfois dans la consigne donnée à l’agent qui a généré la base.

Quatre façons dont une politique présente laisse passer

Ces failles ne font rien planter. Les pages s’affichent et les tests fonctionnels passent, parce qu’ils sont presque toujours écrits avec un seul compte. Voici quatre formes à connaître.

  • La règle qui vérifie la connexion, pas le propriétaire. La politique exige un utilisateur connecté, ou un rôle, sans comparer la ligne à son compte. Dans un banc d’essai de l’éditeur Tenzai, quinze applications construites par cinq agents de code ne comportaient aucune injection SQL ni faille XSS exploitable, mais l’autorisation y était « très mal » appliquée : dans l’une, tout utilisateur doté du rôle « vendeur » pouvait consulter n’importe quelle commande[7].
  • La politique ouverte. Une règle using (true) accordée au rôle anonyme donne à chaque visiteur la lecture de toutes les lignes que ses droits atteignent ; Supabase la réserve aux données faites pour être publiques[6].
  • La vue qui contourne. Les vues ignorent la RLS par défaut, parce qu’elles sont créées avec l’utilisateur postgres : posée sur une table protégée, une vue rend toutes les lignes que ses politiques retenaient[6]. Sur PostgreSQL 15 et plus, l’option security_invoker = true la soumet aux politiques[6].
  • La fonction serveur qui utilise la clé secrète. Appelée avec cette clé, une fonction côté serveur passe outre toutes les politiques[5]. Le contrôle d’appartenance doit alors être écrit dans son code, et testé comme tel.

Rien de tout cela n’est propre à l’IA. L’OWASP place le contrôle d’accès défaillant en tête de son Top 10 2025, avec cet exemple : consulter ou modifier le compte de quelqu’un d’autre en fournissant son identifiant[8]. Le même test vaut donc pour une API écrite à la main, hors de Supabase. Les agents écrivent vite un code qui marche ; la règle d’appartenance, elle, doit leur être donnée.

Chiffre clé

100 %

des applications testées dans les données réunies pour le Top 10 2025 de l’OWASP présentaient au moins une forme de contrôle d’accès défaillant. Le chiffre couvre quarante types de faiblesses et ne mesure pas leur gravité.[8]

Depuis le 30 octobre, une erreur que votre agent saura corriger

Supabase a changé un réglage par défaut le 30 octobre 2026 pour tous les projets existants : une table nouvellement créée dans le schéma public n’est plus exposée d’office à l’API, il faut l’ouvrir par une commande grant[9]. Les tables existantes gardent leurs droits, et le comportement de la RLS ne change pas[9].

Le changement ferme une porte, mais il fait apparaître une erreur. L’application reçoit le code 42501, « permission refusée », avec une indication qui donne la commande à passer, par exemple GRANT SELECT ON public.your_table TO anon;[9]. Supabase l’assume : l’indication est conçue pour qu’un agent se corrige seul[9]. Si la RLS est désactivée, ou si une politique autorise trop de lignes, l’agent qui suit cette indication rouvre ce que le changement voulait fermer, y compris aux visiteurs non connectés quand la commande vise le rôle anonyme. Avec la RLS activée et sans politique applicable, le droit SQL seul ne rend aucune ligne lisible.

Supabase donne la parade : écrire les grant dans la même migration que l’activation de la RLS et les politiques, et mettre à jour les consignes de l’outil d’IA qui crée les tables[9]. Une ligne dans le fichier de consignes de l’agent pose la règle : aucun grant sans politique écrite et testée.

Ces politiques peuvent aussi borner vos agents. Depuis le 22 octobre, Supabase propose de donner à une application son propre serveur MCP, le protocole par lequel un assistant d’IA appelle des outils : « chaque appel d’outil s’exécute en tant qu’utilisateur connecté, si bien que la RLS que vous avez déjà écrite décide de ce que chaque agent atteint »[10]. Dans cette architecture, une politique juste borne aussi l’agent ; une politique fausse lui ouvre les mêmes lignes qu’au client B. Cette protection ne s’étend ni aux connexions qui contournent la RLS, avec une clé secrète par exemple, ni au serveur MCP de développement, qui agit avec les droits du développeur.

Le test des deux comptes, puis le test automatique

Le test qui répond à la question du titre ne demande ni outil ni expertise rare. Il demande une phrase et deux comptes.

  1. Écrire la règle. Une phrase par type de document : « un client ne voit que ses factures ; l’administrateur d’un client voit celles de son entreprise ; un compte désactivé ne voit plus rien ».
  2. Créer deux comptes de test, A et B, rattachés à deux entreprises différentes, avec pour chacun une facture, un devis et un fichier téléversé. Vérifier d’abord que chaque compte retrouve ses propres documents.
  3. Rejouer, connecté en B, les requêtes qui affichent ces trois documents, en remplaçant l’identifiant par celui de A, dans l’adresse ou depuis les outils de développement du navigateur.
  4. Comparer la réponse au refus attendu : liste vide, ou réponse 403 ou 404, selon le contrat de l’API. Une erreur serveur, une requête invalide ou un résultat vide pour les deux comptes ne prouvent rien.
  5. Si la donnée revient, écrire un test automatique qui échoue avant de corriger, puis vérifier qu’il passe après. Conservé et exécuté à chaque changement, il signalera le retour de ce cas à la prochaine génération de code.

Supabase recommande d’écrire ces tests de politiques en SQL et de les lancer avec supabase test db. Sa documentation le dit sans détour : tant que la suite ne passe pas, « vous ne savez pas si les politiques font ce que vous vouliez »[6]. Pour commencer l’inventaire, deux requêtes dans l’éditeur SQL suffisent.

-- Tables publiques sans RLS
select tablename
from pg_tables
where schemaname = 'public'
  and not rowsecurity;

-- Politiques ouvertes à tous
select tablename, policyname,
       roles, cmd
from pg_policies
where schemaname = 'public'
  and (qual = 'true'
       or with_check = 'true');

La seconde ne trouvera pas une règle qui vérifie seulement la connexion. Celle-là, seul le test des deux comptes la révèle.

Deux colonnes séparées par un encadré central. À gauche, ce que le contrôle automatique lit : la configuration de la base, les tables sans RLS, les règles ouvertes à tous, les secrets visibles dans le code, les dépendances vulnérables. À droite, ce qu’il ne peut pas savoir : qui doit voir quelle facture, les rôles propres au métier, ce que voit un compte désactivé, si une politique correspond à l’intention de l’équipe. Au centre, le test des deux comptes relie les deux colonnes en quatre étapes : écrire la règle en une phrase, créer deux comptes dans deux entreprises, demander avec le compte B les documents du compte A, vérifier que la réponse est le refus prévu par l’API, et non une panne, après avoir confirmé que chaque compte lit ses propres documents.
Schéma 2 Le contrôle automatique couvre la colonne de gauche. Celle de droite n’appartient qu’à l’équipe : le test des deux comptes la rend vérifiable.

Un droit se vérifie là où la donnée est servie : ni dans l’interface, ni dans la consigne donnée à l’agent, ni dans le tableau vert de la plateforme. Le contrôle automatique dit que la configuration a été relue. Le test des deux comptes dit si le client B voit la facture du client A. C’est la question que vos clients poseront.

Sources

  1. Lovable Documentation — Security overview

    docs.lovable.dev · non daté · consulté le · Documentation vivante, non datée : sections « Quick scan » et « Deep scan ». Citations traduites par nos soins.

  2. Matt Palmer — Statement on CVE-2025-48757

    mattpalmer.io · publié le · consulté le · Récit du chercheur : découverte le 20 mars 2025, éditeur prévenu le 21 mars.

  3. NIST, National Vulnerability Database — CVE-2025-48757

    nvd.nist.gov · publié le · consulté le · Lue par l’API de la NVD. Note CVSS 3.1 de 9,3 attribuée par le MITRE ; fiche marquée « disputed » par le fournisseur.

  4. Lovable — Lovable’s compliance and your app: what’s covered, what’s your responsibility

    lovable.dev · publié le · consulté le · Citations traduites par nos soins.

  5. Supabase Docs — API keys

    supabase.com · non daté · consulté le · Documentation vivante, non datée : clé publique (publishable, anciennement anon) et clé secrète (anciennement service_role).

  6. Supabase Docs — Row Level Security

    supabase.com · non daté · consulté le · Documentation vivante, non datée : politiques ouvertes, vues et security_invoker, tests de politiques.

  7. Tenzai — Bad Vibes: Comparing the Secure Coding Capabilities of Popular Coding Agents

    tenzai.com · publié le · consulté le · Banc d’essai conçu et noté par un éditeur d’outils de test : 15 applications, 5 agents, essais de décembre 2025. Date affichée sur la page de l’article consultée ; l’index du blog indique le 13 janvier 2026.

  8. OWASP Top 10:2025 — A01:2025 – Broken Access Control

    top10.owasp.org · non daté · consulté le · Édition 2025 du Top 10, page non datée : section « Background » et tableau des scores (40 CWE rattachées).

  9. Supabase — Breaking Change: Tables not exposed to Data and GraphQL API automatically

    supabase.com · publié le · consulté le · Annonce publiée le 28 avril 2026 ; bascule des projets existants le 30 octobre 2026.

  10. Supabase — Give your Supabase app its own MCP server

    supabase.com · publié le · consulté le · Citation traduite par nos soins.

Le scan gratuit

Et chez vous,
qu’est-ce qui est exposé ?

Nous examinons ce que vos équipes et prestataires livrent avec l’IA : code, infrastructure et accès aux données. Un humain relit chaque constat.

Demander le scan gratuit

Scan gratuit. Des failles détectées ? Le rapport détaillé est payant.