Quand fait-on ça ? (le moment exact)
Le moment est clair et non négociable : juste avant de publier ton app ou de la donner à de vrais utilisateurs. Tant que tu testes tout seul sur ton ordinateur, il ne se passe rien. Mais à la seconde où ton app est en ligne avec les données d'autres personnes, sans ces verrous, tu exposes tout. Et comme l'IA ne le fait pas d'elle-même (elle pense à faire fonctionner, pas à protéger), c'est à toi de le demander explicitement.
Verrou 1 · RLS (que chacun ne voie QUE ce qui lui appartient)
Sans RLS, un utilisateur malveillant n'a qu'à changer un ID dans l'URL ou dans une requête pour voir les données de quelqu'un d'autre. C'est la vulnérabilité la plus courante dans les apps avec Supabase et PostgreSQL — et la plus facile à exploiter. C'est pour ça que c'est le verrou n°1.
J'utilise Supabase avec PostgreSQL. J'ai ces tables : [liste tes tables et leurs colonnes d'utilisateur, ex : posts (user_id), comments (post_id, user_id)]. Configure Row-Level Security pour que chaque utilisateur ne puisse voir/modifier/supprimer que ses propres enregistrements. Suis les meilleures pratiques officielles de Supabase : - Active RLS sur TOUTES les tables (ENABLE ROW LEVEL SECURITY). - Crée des politiques SÉPARÉES pour SELECT, INSERT, UPDATE et DELETE (N'utilise PAS FOR ALL). - IMPORTANT pour la performance : enveloppe la fonction d'utilisateur comme (SELECT auth.uid()), PAS auth.uid() seul, pour que Postgres l'évalue une seule fois par requête et non une fois par ligne. - Restreins les politiques au rôle authenticated (TO authenticated), pas à public, pour que les visiteurs anonymes ne touchent même pas la table. - N'utilise JAMAIS user_metadata dans les politiques (l'utilisateur peut le modifier). - Ajoute des index sur les colonnes utilisées par les politiques (ex. user_id). - Rappelle-toi : pour qu'un UPDATE fonctionne, il faut aussi une politique de SELECT. - Donne-moi le SQL complet prêt à coller dans le SQL Editor de Supabase, et explique-moi en une ligne ce que fait chaque politique.
auth.uid() directement dans la politique. MAIS ça fait que Postgres l'évalue une fois par ligne — dans une table de 100 000 lignes, la différence est entre une requête de 5 millisecondes et une de 5 secondes ! L'astuce (documentée par Supabase) : écris-le comme `(SELECT auth.uid())`. Ainsi il n'est évalué qu'une seule fois. C'est pour ça que le prompt ci-dessus le demande explicitement.- Crée deux utilisateurs de test dans ton app.
- Connecte-toi avec l'utilisateur A et crée un enregistrement.
- Connecte-toi avec l'utilisateur B : il ne doit PAS voir l'enregistrement de A.
- Consulte le Security Advisor de Supabase : il te prévient si tu as laissé une table sans RLS.
Verrou 2 · CORS (qui peut appeler ton API)
Configure CORS sur mon backend pour que SEUL mon domaine de production (https://mon-app.com) et localhost en développement puissent faire des requêtes. - N'utilise PAS "*" comme origine autorisée en production. - N'autorise que les méthodes que j'utilise vraiment (ex. GET, POST, PUT, DELETE). - N'autorise que les en-têtes dont j'ai besoin. - Explique-moi exactement où mettre chaque chose selon ma stack : [dis-moi ton framework/backend].
Access-Control-Allow-Origin: * avec les credentials activés. C'est comme laisser la porte ouverte et poser une pancarte qui dit « entrez, j'ai laissé les clés à l'intérieur ». Si ton IA te l'a configuré comme ça « pour que ça marche vite », corrige-le avant de publier.Verrou 3 · Security Headers (consignes de défense au navigateur)
Ajoute les headers de sécurité recommandés à mon app : Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Strict-Transport-Security (HSTS) et Permissions-Policy. - Explique-moi ce que fait chacun en une ligne simple. - Donne-moi la configuration prête pour mon framework : [dis-moi lequel tu utilises, ex. Next.js, Express]. - Commence la Content-Security-Policy en mode report-only pour ne rien casser, et dis-moi comment la durcir ensuite. - Dis-moi comment vérifier le résultat.
L'habitude · vérifie-le avant chaque publication
- RLS activé sur toutes les tables avec des données d'utilisateurs (et testé avec 2 comptes).
- CORS restreint à tes domaines, jamais
*avec credentials. - Headers en place et avec une note A sur securityheaders.com.
- Tes secrets (.env, clés d'API) JAMAIS envoyés sur GitHub (voir le guide GitHub de la série).
- Tu as consulté le Security Advisor de Supabase et il ne reste aucun avertissement en rouge.