Étude de cas
Étude de cas : un paywall Supabase contourné en deux requêtes
Sur une plateforme d'éducation crypto par abonnement, la page d'inscription gratuite suffisait à débloquer le contenu payant. Voici la chaîne technique, ce qui tenait, les correctifs et la leçon pour les agents IA.
Par Florian Bonamy · Mis à jour le 2026-10-29
Chiffres clés
| Élément | Constat |
|---|---|
| Type de cible | Plateforme d'éducation crypto par abonnement (Next.js + Supabase) |
| Point d'entrée | Une inscription gratuite, confirmée automatiquement, sans vérification d'e-mail |
| Impact | Tout le contenu premium lisible sans payer, y compris des alertes sensibles au temps |
| Requêtes nécessaires | 2 (créer un compte, lire la table de contenu) |
| Ce qui tenait | Écritures bloquées par RLS pour les anonymes, profils, abonnements et listes de suivi protégés, aucun stockage de fichiers exposé |
| Priorité de correction | Immédiate pour la politique RLS, sous une semaine pour le reste |
Que s'est-il passé exactement sur cette plateforme ?
Une plateforme d'éducation crypto par abonnement a laissé n'importe quel visiteur lire son contenu réservé aux membres. Le contournement tenait en deux requêtes : créer un compte gratuit, puis interroger la table de contenu avec le jeton obtenu.
Le cadre compte. C'était un audit externe et passif, réalisé début 2026 sans mandat écrit ni mission payée, sur des éléments accessibles publiquement. Aucune intrusion, aucune exploitation au-delà de la confirmation de lisibilité, aucune donnée téléchargée. Pour comparer l'accès anonyme et l'accès connecté, un seul compte de test gratuit a été créé avec une adresse générique, puis déconnecté et son jeton invalidé à la fin. Les résultats ont ensuite été transmis au propriétaire dans le cadre d'une divulgation responsable, avec la liste des corrections à faire et le compte de test à supprimer.
Cette étude de cas est anonymisée : la plateforme, ses dirigeants et son domaine restent dans l'ombre. Le schéma, lui, est très courant sur les applications construites avec Supabase.
Pourquoi une page de capture d'e-mails débloque-t-elle le cours payant ?
Parce que l'inscription gratuite produit un vrai jeton d'authentification, et que ce jeton ouvre plus que ce que le propriétaire imaginait. La page d'inscription servait à collecter des adresses e-mail, c'est-à-dire un outil marketing. Techniquement, c'est une porte d'entrée vers la base de données.
Le propriétaire pensait que le paywall protégeait son contenu. Il protégeait en réalité l'affichage : le site montrait « ressource introuvable » aux non-abonnés, mais l'API de la base renvoyait le texte complet à tout compte connecté. Un paywall qui vit dans l'interface se contourne en parlant directement à l'API.
C'est la leçon à retenir pour un dirigeant : chaque page qui crée un compte est une page qui distribue un jeton. Demandez-vous ce que ce jeton permet de lire, au-delà de ce que l'écran affiche.
Quelle est la chaîne technique, étape par étape ?
La chaîne tient en trois maillons, et il suffit qu'un seul soit solide pour qu'elle casse.
- Inscription ouverte avec confirmation automatique. Le service d'authentification acceptait n'importe quelle adresse et validait le compte immédiatement, sans e-mail de vérification ni CAPTCHA.
- Politique RLS trop large. La règle de sécurité au niveau des lignes (RLS) de la table de contenu vérifiait que le rôle était « authenticated ». Elle ne vérifiait pas que l'utilisateur avait un abonnement actif.
- Contenu premium dans la même table que le contenu public. Un simple filtre sur la visibilité suffisait à récupérer les articles réservés, texte complet compris.
| Maillon | Ce qui était en place | Ce qu'il fallait |
|---|---|---|
| Inscription | Ouverte, confirmée automatiquement | Confirmation d'e-mail, CAPTCHA, ou inscription liée au paiement |
| Politique RLS | « Connecté » suffit | « Abonnement actif » exigé pour la visibilité membres |
| Modèle de données | Public et premium mélangés sans contrôle de droit | Droit vérifié côté serveur à chaque lecture |
Un point mérite d'être souligné : corriger seulement l'inscription ne suffit pas. Même avec une confirmation d'e-mail, n'importe qui avec une vraie adresse reste « authentifié ». Le correctif décisif est la politique RLS.
Qu'est-ce qui était bien sécurisé ?
Le socle était sain, ce qui rend le défaut d'autant plus instructif. Les points suivants tenaient :
- Écritures bloquées : les tentatives d'insertion anonymes étaient rejetées par RLS sur les tables testées.
- Données personnelles protégées : profils, abonnements et listes de suivi ne revenaient rien aux visiteurs anonymes, et un compte connecté ne voyait que ses propres lignes.
- Stockage fermé : aucun compartiment de fichiers lisible publiquement.
- Clé publique correctement traitée : la clé « anon » visible dans le code du navigateur est faite pour être publique. Elle ne constitue pas une faille : la frontière de sécurité est la RLS.
L'équipe avait donc fait la partie difficile. Elle a oublié une seule question : « qui a le droit de lire cette ligne ? »
Quels autres constats l'audit a-t-il relevés ?
Les autres constats, classés par gravité, pèsent moins que le contournement mais racontent la même histoire d'hygiène.
| Gravité | Nature du constat |
|---|---|
| Critique | Contournement du paywall par un compte gratuit |
| Élevée | Inscription ouverte avec confirmation automatique (cause racine) |
| Élevée | Table de configuration lisible sans authentification, révélant la structure tarifaire |
| À vérifier | Droits de modification de cette table non confirmés, laissés au propriétaire à contrôler : je n'ai volontairement pas testé sur des lignes réelles |
| Moyenne | Protection de l'e-mail faible (usurpation de l'expéditeur possible), identifiant de suivi d'erreurs exposé, en-tête de politique de contenu absent |
| Faible | Clés publiques de test et de production mélangées, DNS sans signature, lecture en masse d'articles déjà publics |
| Information | Sous-domaines visibles via les certificats, outils tiers standards |
Le cas de la table de configuration illustre une règle du métier : quand un test risquerait de modifier des données réelles, on s'arrête et on signale le doute au propriétaire.
Comment corriger ce type de faille ?
La correction est courte, et la priorité va à la politique RLS. Voici l'ordre recommandé.
- Lier la lecture au statut d'abonnement. La politique RLS doit exiger un abonnement actif pour toute ligne marquée « membres ». Le droit se vérifie dans la base, pas dans l'interface. Voir la documentation Row Level Security de Supabase.
- Fermer l'inscription automatique. Activer la confirmation d'e-mail, ajouter un CAPTCHA, ou conditionner la création de compte au paiement.
- Vérifier les droits côté serveur. Pour le contenu de valeur, passer par une fonction serveur qui contrôle l'abonnement à chaque lecture, plutôt que d'exposer la table.
- Ne pas exposer la table de configuration. Servir les réglages depuis le serveur, ou limiter la lecture aux rôles qui en ont besoin.
- Contrôler UPDATE et DELETE. Un INSERT bloqué ne dit rien des autres opérations.
- Durcir le périmètre. Authentification d'e-mail stricte, politique de contenu, clés de test retirées des versions de production.
Ces points relèvent des familles « autorisation défaillante » décrites par l'OWASP, notamment API1 (autorisation au niveau des objets) et API5 (autorisation au niveau des fonctions). Pour approfondir les pièges de la RLS, lisez notre guide sur les erreurs RLS et les cinq erreurs de configuration qui contournent un paywall.
Quel rapport avec les agents IA ?
Un agent ou un chatbot branché sur la même base avec le jeton d'un utilisateur hérite exactement de la même lecture trop large. Si la base répond « oui » à tout compte connecté, l'agent répondra « oui » aussi, et un utilisateur malveillant peut lui demander de résumer, citer ou envoyer ailleurs ce que la politique laisse passer.
C'est le risque central des agents : le modèle n'est pas un contrôle d'accès. Une consigne dans le prompt du type « ne montre le contenu premium qu'aux abonnés » est une règle souple, qu'une injection de prompt peut contourner. Le droit doit être vérifié en dehors du modèle, dans la base ou dans une couche d'autorisation qui décide avant l'appel d'outil.
Pour un agent connecté à vos données, testez au minimum :
- ce qu'un compte gratuit, ou le compte d'un autre client, peut lui faire lire ;
- si les outils de l'agent portent le jeton de l'utilisateur ou une clé de service, plus large ;
- si les droits sont revérifiés à chaque appel, pas seulement à l'ouverture de session.
Ces vérifications correspondent à la surface décrite dans notre page sur la sécurité des agents IA, et c'est le terrain d'un red team d'agent IA. L'article sur l'isolation des données d'un agent multi-tenant détaille le même problème côté agent, et l'étude de cas du webhook n8n montre une autre chaîne où un contrôle manquant a suffi.
Comment CleanIssue peut-il vous aider ?
Si votre produit mélange comptes utilisateurs, contenu payant et un agent IA, la question à poser est simple : un compte gratuit peut-il lire ce qu'il ne devrait pas, directement ou par l'intermédiaire de l'agent ? Le Red Team Agent Express répond à cette question en 5 jours pour 1 900 €, sur un agent précis, avec un rapport écrit et des preuves reproductibles. Il est toujours payant : aucune garantie « rien trouvé, rien payé ».
Le premier contact est un rendez-vous découverte gratuit de 30 minutes, consacré à cadrer le périmètre avant toute proposition.
Les autres études de cas
Questions fréquentes
Cet audit était-il autorisé ?
Il s'agissait d'un audit externe et passif, sans mandat écrit ni mission payée, limité à des éléments publiquement accessibles. Un seul compte de test gratuit a servi à comparer l'accès anonyme et l'accès connecté, puis il a été déconnecté et son jeton invalidé. Les résultats ont été transmis au propriétaire par divulgation responsable.
Des données d'utilisateurs ont-elles été téléchargées ?
Non. La lisibilité du contenu a été confirmée et les lignes comptées, puis les tests se sont arrêtés. Aucun contenu premium ni donnée personnelle n'a été téléchargé ou conservé, et les fichiers temporaires ont été supprimés.
Pourquoi un compte gratuit pouvait-il lire le contenu payant ?
La politique RLS de la table de contenu vérifiait que l'utilisateur était authentifié, pas qu'il avait un abonnement actif. Comme l'inscription était ouverte et confirmée automatiquement, n'importe qui obtenait un jeton valide en une requête.
Activer la confirmation d'e-mail suffit-il à corriger le problème ?
Non. Quelqu'un avec une vraie adresse reste authentifié après confirmation. Le correctif décisif est une politique RLS qui exige un abonnement actif pour le contenu réservé, la confirmation d'e-mail et le CAPTCHA réduisant seulement la création de comptes en masse.
Une clé « anon » Supabase visible dans le navigateur est-elle une faille ?
Non, cette clé est conçue pour être publique. La vraie frontière de sécurité est la RLS : si les politiques sont correctes, la clé publique ne donne accès qu'à ce que vous avez décidé d'exposer.
Quel risque pour un agent IA branché sur la même base ?
Si l'agent utilise le jeton d'un utilisateur, il hérite de la même lecture trop large et peut résumer ou transmettre ce que la politique laisse passer. Le droit d'accès doit être vérifié hors du modèle, dans la base ou dans une couche d'autorisation placée avant l'appel d'outil.
À lire aussi
- Stripe : 5 erreurs qui permettent de contourner le paywallClé secrète dans le bundle, accès via la page de succès, webhook non signé, prix fixé par le client, essais illimités : 5 failles Stripe à tester.
- Erreurs RLS : le guide 2026 pour Supabase et PostgreSQLPolitiques incomplètes, WITH CHECK oublié, JWT périmé, service_role exposé, vues et fonctions qui contournent la RLS : les erreurs et comment les tester.
- Supabase vs Firebase : comparaison sécurité et faillesRLS PostgreSQL contre règles Firestore : les failles propres à chaque backend, les erreurs communes et les tests pour vérifier ce qu’un utilisateur lit.
- Agent IA multi-tenant : isoler les données de chaque clientIsoler les données de chaque client dans un agent IA multi-tenant : appels d'outils, mémoire et RAG, avec six tests à passer avant la mise en production.
- Function calling : la surface d'attaque des agents IAFunction calling et agents IA : cinq familles d'attaques sur les outils, conception sûre et protocole de test pour limiter les actions non autorisées.
- Excessive Agency (LLM06) : limiter un agent IAExcessive Agency (OWASP LLM06:2025) : réduire les fonctions, les permissions et l'autonomie d'un agent IA, avec un plan de test concret.