00:00:00Un rapport publié ce mois-ci a analysé environ 20 000 applications indés et a révélé qu'une sur neuf
00:00:04exposait des identifiants Supabase dans le code front-end.
00:00:08Et on ne parle pas d'un log serveur ou d'un dépôt privé.
00:00:11C'est juste dans le JavaScript que chaque visiteur télécharge.
00:00:14Le pire, c'est que ces applis n'ont pas été piratées, elles ont juste publié le secret par erreur.
00:00:18Soyons clairs : certaines clés sont censées être publiques.
00:00:21Le problème vient du pipeline de déploiement, car la même erreur peut envoyer une clé qui ne devrait
00:00:25jamais se retrouver dans le navigateur.
00:00:27Nous publions des vidéos en permanence.
00:00:28N'oubliez pas de vous abonner.
00:00:35Voici la vérité toute simple qui piège pas mal de monde.
00:00:38On le sait tous, mais c'est facile de l'oublier quand on travaille dans l'urgence.
00:00:41Quand on marque une variable d'environnement comme publique, l'outil de build considère qu'elle
00:00:46appartient au navigateur et l'ajoute au bundle client.
00:00:50Next.js utilise le préfixe "NEXT_PUBLIC", Vite utilise "VITE_" et SvelteKit utilise
00:00:56"public".
00:00:57Le mot "public" n'est pas une étiquette de sécurité, c'est littéralement le bon d'expédition.
00:01:01Maintenant que c'est dit, passons à la partie concernant Supabase.
00:01:04Certaines clés sont prévues pour être publiques, comme les clés "anon" ou "publishable",
00:01:10et d'autres sont privées, comme les clés "service_role" ou les clés secrètes.
00:01:12Si une clé privée atterrit dans le navigateur, vous devinez sans doute la suite.
00:01:17La sécurité au niveau des lignes (RLS) ne vous sauvera pas dans ce cas.
00:01:20La doc de Supabase est claire : les clés de service contournent la RLS.
00:01:24Donc si cette clé est dans votre front-end, tout votre travail sur les politiques de sécurité ne sert plus à rien.
00:01:29Laissez-moi vous montrer exactement comment ça arrive avec mon propre bac à sable.
00:01:33D'abord, j'ai créé une application CRUD simple avec Next.js et j'y ai lié mon instance Supabase.
00:01:38Voici mon fichier .env, et voici l'erreur.
00:01:41J'ai mis une clé derrière une variable préfixée par "public".
00:01:45Cette clé est censée être publique, donc c'est normal qu'elle soit visible.
00:01:48Le vrai souci, c'est que ce même chemin "NEXT_PUBLIC" peut accidentellement envoyer une clé privée.
00:01:53J'ai lancé "npm run build" pour générer le projet, puis j'ai démarré l'appli.
00:01:59Me voici dans Chrome.
00:02:00Je vais ajouter rapidement quelques infos dans la base de données de notre appli CRUD.
00:02:05Ok, maintenant je peux ouvrir le bundle JavaScript compilé et je vais faire une recherche.
00:02:10La voilà.
00:02:12L'URL et la clé sont littéralement présentes dans le fichier que vos utilisateurs viennent de charger
00:02:18dans leur navigateur.
00:02:19Et remarquez bien ce qui ne s'est PAS passé.
00:02:21Personne n'a eu besoin de forcer l'entrée.
00:02:22Je l'ai juste trouvé, d'accord ?
00:02:24Personne n'a exploité de faille complexe.
00:02:25Il suffit de lire ce que l'application a déjà envoyé sur l'internet public.
00:02:29Si vous pouvez le voir, n'importe qui peut le voir.
00:02:32Ouvrez les outils de développement, regardez les fichiers JS et cherchez la clé.
00:02:35C'est tout ce qu'il y a à faire.
00:02:36Alors si votre plan est de vous dire que personne n'ira regarder, sachez que le web regorge de gens et de bots
00:02:41dont le seul travail est de traquer ce genre d'erreurs.
00:02:44Voici donc la solution qui fonctionne vraiment.
00:02:47Le navigateur ne devrait appeler que votre propre API.
00:02:50Votre API s'exécute côté serveur.
00:02:52C'est là que résident les clés privées.
00:02:54Déplacez l'opération privée dans une route API ou une fonction serveur.
00:02:58Le client appelle votre endpoint, votre endpoint appelle Supabase, puis vous rebuildez et vérifiez
00:03:03le bundle.
00:03:04Si la clé a disparu du bundle, c'est réparé, mais ne vous arrêtez pas là
00:03:09car il y a d'autres précautions à prendre.
00:03:11Vérifiez que la RLS est activée sur les tables accessibles aux utilisateurs et que vos politiques
00:03:16font bien ce que vous croyez.
00:03:18Prenez aussi le temps de faire des tests.
00:03:19C'est une étape qu'on a trop souvent tendance à négliger.
00:03:21Pour éviter que le problème ne revienne : la plupart des gens corrigent ça une fois, puis réintroduisent
00:03:26l'erreur plus tard dans un moment de rush.
00:03:28Ajoutez des garde-fous, commencez par un scan de secrets dans votre CI pour bloquer le build
00:03:34si une clé apparaît là où elle ne devrait pas.
00:03:36Ensuite, instaurez une règle pour les PR : tout ce qui est "NEXT_PUBLIC" ou "VITE_" est considéré
00:03:41comme public par défaut, parce que c'est le cas.
00:03:42Enfin, pratiquez la rotation des clés.
00:03:43Au moindre doute sur une possible exposition, renouvelez-les immédiatement.
00:03:47C'est bien mieux que d'attendre de voir les dégâts dans quelques jours.
00:03:50Voici ce que vous pouvez tester dès maintenant.
00:03:52Générez le build de votre application comme pour une mise en production.
00:03:55Cherchez dans le résultat des termes comme "supabase", "JWT", "service_role" ou tout ce qui ressemble à un token.
00:04:01Si vous trouvez quelque chose de privé, considérez qu'il est compromis puisque vous l'avez trouvé.
00:04:05Changez la clé et revoyez votre logique côté serveur.
00:04:08S'il y a une seule phrase à retenir de cette vidéo, c'est celle-ci :
00:04:11Si c'est dans le bundle, c'est public.
00:04:13On se retrouve dans une prochaine vidéo.