Rustine

Supabase vs Firebase : lequel est le plus sûr pour ton app ?

Deux armoires serveur côte à côte : l'une a une porte orange entrouverte qui laisse fuir des points de données, l'autre est fermée et ordonnée.

Supabase vs Firebase : lequel est le plus sûr pour ton app ?
Sommaire
  1. Ce qui change vraiment : deux modèles de sécurité
  2. Le vrai danger : ce que chaque plateforme laisse ouvert par défaut
  3. Côté Supabase : la RLS n'est pas activée par défaut
  4. Côté Firebase : les règles de démarrage
  5. Les clés : lesquelles sont des secrets ?
  6. Firebase : la clé API du navigateur n'est pas un secret
  7. Supabase : une clé à exposer, une clé à protéger
  8. Le tableau comparatif
  9. Les failles typiques côté Firebase
  10. Les failles typiques côté Supabase
  11. Lequel choisir ? Par scénario
  12. Le prompt à coller dans ton agent
  13. Si tu es sur Supabase
  14. Si tu es sur Firebase
  15. Questions fréquentes
  16. Supabase est-il plus sûr que Firebase ?
  17. La clé API Firebase est-elle un secret à cacher ?
  18. Faut-il activer la RLS sur toutes les tables Supabase ?
  19. Quelle est la différence entre clé anon et clé service_role ?
  20. Puis-je migrer de Firebase vers Supabase ?
  21. Sources

La réponse tient en une phrase : Supabase et Firebase peuvent tous deux être parfaitement sûrs, et tous deux peuvent fuiter en une soirée. La différence n'est pas dans l'outil, mais dans le modèle de sécurité. Firebase protège tes données avec des règles déclaratives, écrites séparément pour chaque service (Firestore, Storage, Realtime Database). Supabase s'appuie sur la Row Level Security de PostgreSQL, des règles SQL exécutées au cœur de la base. Pour un projet codé avec l'IA, le danger numéro un est identique des deux côtés : la configuration par défaut laissée ouverte.

Si tu construis un SaaS avec Claude Code, Cursor ou Lovable, cet article t'aide à choisir, puis à verrouiller l'un ou l'autre avec un prompt prêt à coller en fin d'article.

Ce qui change vraiment : deux modèles de sécurité

Firebase est un service géré par Google. Ta donnée vit dans une base NoSQL (Firestore), une base temps réel (Realtime Database) ou des fichiers (Cloud Storage). Chacun de ces services est protégé par ses propres Security Rules : un petit langage déclaratif, de type expression, évalué côté serveur à chaque requête. Une règle Firestore ressemble à une condition : allow read, write: if request.auth != null;. Elle dit « qui peut faire quoi, sur quel chemin », et c'est Google qui l'applique.

Supabase est une couche autour de PostgreSQL. Ta donnée vit dans une base relationnelle classique, avec des tables et des lignes. La protection vient de la Row Level Security (RLS), une fonctionnalité native de Postgres : tu écris des policies en SQL, et la base ajoute automatiquement un filtre à chaque requête. Une policy « un utilisateur ne voit que ses propres lignes » se traduit, sous le capot, par un WHERE auth.uid() = user_id ajouté à chaque SELECT.

La différence de fond : Firebase vérifie à la porte d'entrée du service, Supabase filtre à l'intérieur de la base, au niveau de chaque ligne. Les deux approches marchent. Elles ne cassent pas au même endroit quand on se trompe.

Deux modèles de sécurité comparés : une porte contrôlée à l'entrée à gauche, et un filtre sur les lignes d'une table à droite, avec une ligne surlignée en orange.

Le vrai danger : ce que chaque plateforme laisse ouvert par défaut

C'est ici que les deux plateformes se rejoignent, et c'est la première chose à vérifier quand une app sort d'un générateur.

Côté Supabase : la RLS n'est pas activée par défaut

Quand tu crées une table dans Supabase, la Row Level Security est désactivée. Tant que tu ne l'actives pas, la table est lisible et modifiable par n'importe quel rôle qui a un accès dessus. Or, sur les projets existants, une nouvelle table du schéma public reçoit automatiquement tous les privilèges pour les rôles anon, authenticated et service_role.

Résultat : une table fraîchement créée par ton agent, sans RLS, est un accès libre. Et le piège est double : ajouter une policy ne retire pas les droits déjà accordés. Si tu actives la RLS mais que tu ne révoques pas les privilèges par défaut, anon garde un chemin d'écriture ouvert. La documentation Supabase le dit noir sur blanc : active la RLS sur chaque table exposée, puis révoque les privilèges inutiles. Je détaille la procédure complète dans mon guide pour sécuriser ton app avec la Row Level Security.

Côté Firebase : les règles de démarrage

À la création d'une base Firestore, Firebase te propose deux points de départ : un mode « production », où les règles refusent tout par défaut, et un mode « test », où les règles autorisent tout pendant une période limitée. Beaucoup d'apps générées démarrent en mode test, le temps de prototyper, puis partent en production sans avoir resserré les règles.

Le réflexe dangereux, côté Firebase, c'est la règle fourre-tout : allow read, write: if true;. Elle signifie « tout le monde peut lire et écrire partout ». Une seule ligne, et toute ta base est ouverte.

Dans les deux cas, la cause racine est la même : l'agent d'IA écrit du code fonctionnel, pas du code verrouillé. Le générateur branche la base et ça marche. La sécurité, elle, ne se voit pas au premier chargement.

Les clés : lesquelles sont des secrets ?

La confusion sur les clés est l'une des plus grosses sources d'erreurs, et elle n'est pas la même d'une plateforme à l'autre.

Firebase : la clé API du navigateur n'est pas un secret

Le SDK Firebase s'initialise avec un objet de config : apiKey, authDomain, projectId, etc. Ce bloc est visible dans le code source du navigateur, et c'est normal. La apiKey Firebase n'est pas une clé secrète : c'est un identifiant de projet. Elle ne donne aucun accès à elle seule. La sécurité est portée par les Security Rules et, en complément, par App Check. Ne perds pas ton temps à vouloir la cacher ; concentre-toi sur les règles.

Supabase : une clé à exposer, une clé à protéger

Supabase distingue deux types de clés, et la frontière est simple. La clé publishable (l'ancienne clé anon) est faite pour être embarquée dans le navigateur : elle n'atteint que ce que la RLS autorise. La clé secret (l'ancienne clé service_role) contourne entièrement la RLS : elle porte l'attribut BYPASSRLS et donne un accès complet à toutes tes données.

La règle : la clé secret ne sort jamais du serveur, d'une Edge Function ou d'un job. Jamais dans le navigateur, jamais dans le code source livré. Si ton agent a collé une service_role dans un fichier .js du frontend, c'est une fuite totale, pas un simple réglage. J'explique la frontière exacte dans mon article sur la clé anon et la clé service_role.

À noter : Supabase documente le remplacement des clés anon et service_role par les clés publishable et secret d'ici fin 2026. Le principe, lui, ne change pas : une clé publique, une clé secrète.

Le tableau comparatif

Critère Firebase Supabase
Type de base NoSQL (Firestore, Realtime Database) PostgreSQL relationnel
Modèle de sécurité Security Rules déclaratives, par service Row Level Security en SQL, dans la base
Active par défaut Mode test possible au démarrage RLS désactivée par défaut sur les tables
Clé à exposer apiKey (identifiant, pas un secret) Clé publishable (limitée par la RLS)
Clé à protéger Comptes de service Admin SDK Clé secret (BYPASSRLS)
Autohébergement Non, Google Cloud uniquement Oui, open source
Défense en profondeur Règles + App Check RLS + privilèges Postgres

Les failles typiques côté Firebase

Les oublis se répètent d'une app générée à l'autre. Voici les quatre à vérifier.

La règle ouverte. allow read, write: if true; sur Firestore ou Storage. C'est la plus courante et la plus grave. Elle ouvre la lecture et l'écriture à n'importe qui.

Des règles par service oubliées. Protéger Firestore ne protège pas Storage ni Realtime Database. Chaque service a ses propres règles, dans des fichiers séparés. Une app qui verrouille sa base mais laisse son bucket Storage en lecture publique fuit les fichiers uploadés.

Des chemins trop larges. match /{document=**} attrape tout, y compris des collections que tu croyais internes. Plus le chemin est large, plus le risque d'exposer un champ que tu n'avais pas prévu.

L'absence de validation d'écriture. Même avec request.auth != null, une règle qui n'inspecte pas le contenu laisse un utilisateur connecté écrire n'importe quoi, y compris écraser le champ role d'un autre document. Une bonne règle vérifie à la fois qui écrit et quoi.

Les failles typiques côté Supabase

Même logique, sur les points de fragilité propres à Postgres.

RLS désactivée. La table existe, ton app la lit et l'écrit, et personne n'a activé la RLS. Tant qu'elle est off, la clé publishable atteint tout. C'est l'équivalent exact de la règle Firebase ouverte.

La clé secret dans le frontend. Une service_role (ou une clé secret) collée côté client contourne toutes les policies que tu auras écrites. Le correctif n'est pas une policy, c'est une rotation de clé.

Des policies trop permissives. Une policy using (true) ouverte à anon rend une table publique, ligne par ligne. Le piège classique, c'est la policy « les profils sont visibles par tout le monde » qui embarque aussi l'adresse e-mail ou le numéro.

Le bucket Storage public. Supabase crée par défaut un bucket public dont les fichiers sont accessibles sans authentification. Y stocker un document privé, un export ou une capture, c'est le rendre téléchargeable par URL. C'est la variante Supabase du Storage Firebase ouvert.

Un point commun à tout ça : quand une API renvoie les données d'un autre utilisateur à cause d'un identifiant non vérifié, on parle de faille IDOR. C'est exactement le genre de fuite que ces mauvaises configs produisent.

Lequel choisir ? Par scénario

Il n'y a pas de vainqueur absolu, il y a des scénarios.

Tu vibecodes un MVP et tu veux aller vite. Les deux conviennent, mais Firebase est souvent plus rapide à démarrer : pas de schéma à penser, un SDK qui se branche en quelques lignes. Le coût, c'est qu'il faut penser aux règles tôt, sinon tu publies en mode test.

Tu tiens à des données relationnelles propres (jointures, contraintes, migrations). Supabase gagne. PostgreSQL est fait pour ça, et la RLS est une vraie défense en profondeur : elle protège tes données même si un accès passe par un outil tiers ou une API oubliée.

Tu veux de l'autohébergement ou de la souveraineté. Supabase est open source et peut tourner sur ton infrastructure, avec des régions en Europe. Firebase est verrouillé sur Google Cloud. Pour une app qui traite des données personnelles en France, ce point compte au moment de remplir tes obligations RGPD.

Tu as déjà choisi ton outil de génération. Les apps Lovable génèrent par défaut du Supabase ; les gabarits Firebase sont plus courants côté certains prompts. Ne te bats pas contre ton outil : choisis la plateforme que ton agent sait bien câbler, puis verrouille-la. J'ai listé les failles typiques d'une app Lovable si c'est ton cas.

Dans tous les cas, le choix de la plateforme importe moins que la configuration que tu laisses derrière toi.

Le prompt à coller dans ton agent

Voici la rustine. Colle le prompt correspondant à ta plateforme dans Cursor, Claude Code ou Lovable, puis laisse l'agent faire les vérifications.

Si tu es sur Supabase

text
Passe en revue le schéma public de mon projet Supabase. Pour chaque table exposée :

1. Active la Row Level Security : ALTER TABLE <table> ENABLE ROW LEVEL SECURITY;
2. Révoque les privilèges par défaut du rôle anon sur les tables qui ne sont pas publiques :
   REVOKE ALL ON <table> FROM anon;
3. Ajoute une policy SELECT/INSERT/UPDATE adaptée, par exemple :
   CREATE POLICY "user owns row" ON <table> FOR ALL TO authenticated
   USING (auth.uid() = user_id) WITH CHECK (auth.uid() = user_id);
4. Vérifie qu'aucune clé service_role ou clé secret n'apparaît dans le code frontend
   (cherche sb_secret_ ou service_role dans les fichiers .tsx/.js livrés au navigateur).
5. Vérifie ensuite que la clé publishable seule ne peut plus lire une ligne qui ne
   m'appartient pas, en testant une requête sans session.

Si tu es sur Firebase

text
Passe en revue mes Security Rules Firebase. Pour Firestore, Storage et Realtime Database :

1. Remplace toute règle du type allow read, write: if true; par des règles qui
   exigent une session ET valident la donnée.
2. Exemple Firestore minimal à adapter :
   match /users/{userId} {
     allow read, write: if request.auth != null && request.auth.uid == userId;
   }
3. Sur Storage, restreins la lecture des fichiers privés aux utilisateurs connectés :
   match /{allPaths=**} { allow read, write: if request.auth != null; }
4. Vérifie que la config Firebase exposée dans le navigateur ne contient que apiKey,
   authDomain et projectId, et aucune clé de compte de service.
5. Vérifie ensuite qu'une requête non authentifiée est bien refusée sur chacune des
   trois bases.

Questions fréquentes

Supabase est-il plus sûr que Firebase ?

Pas intrinsèquement. Les deux offrent un niveau de sécurité équivalent une fois bien configurés. La différence est structurelle : Supabase filtre au niveau des lignes dans PostgreSQL, Firebase applique des règles déclaratives par service. Le risque réel, des deux côtés, vient de la configuration laissée ouverte par défaut.

La clé API Firebase est-elle un secret à cacher ?

Non. La apiKey visible dans le navigateur est un identifiant de projet, pas une clé secrète. La sécurité Firebase repose sur les Security Rules et App Check. La cacher ne protège rien ; resserrer les règles, si.

Faut-il activer la RLS sur toutes les tables Supabase ?

Oui, sur chaque table exposée. Une table sans RLS est accessible à tout rôle qui a un privilège dessus. Active la RLS, puis révoque les privilèges inutiles, car ajouter des policies ne retire pas les droits déjà accordés.

Quelle est la différence entre clé anon et clé service_role ?

La clé anon (désormais publishable) est limitée par la RLS et peut rester dans le navigateur. La clé service_role (désormais secret) contourne la RLS et donne un accès complet : elle ne doit jamais quitter le serveur.

Puis-je migrer de Firebase vers Supabase ?

Oui, mais c'est un vrai chantier : les données NoSQL doivent être modélisées en tables relationnelles, et les règles réécrites en policies SQL. Si la souveraineté ou le SQL est ton critère, cela peut valoir le coup ; sinon, verrouiller Firebase est plus rapide que migrer.

Sources


Avant de trancher définitivement entre Supabase et Firebase, une chose est sûre : la faille ne vient presque jamais de la plateforme, mais du réglage que l'agent a laissé derrière lui. Vérifie ton site avec Rustine : le scan regarde ton app comme le ferait un inconnu, te montre ce qui fuit avec la requête exacte, et te donne le correctif à coller dans Cursor, Claude Code ou Lovable.

Ton app est-elle touchée ? Regarde en une minute.Scanner mon site