// docs / security guides / pre-launch SaaS
Checklist sécurité pré-lancement SaaS : 35+ items
Vous êtes à quelques jours du lancement d'un produit SaaS créé avec Cursor, Claude Code, Lovable ou Bolt. Cette liste de contrôle est un audit go/no-go couvrant les aspects de sécurité qui manquent systématiquement aux outils AI et que les fondateurs qui expédient rapidement doivent aborder avant de prendre l'argent des clients. Huit sections, plus de 35 éléments, chacun pouvant être résolu en 30 à 90 minutes. Imprimez-le, rayez-le, déployez-le en toute confiance.
Chaque élément ci-dessous est essentiel. Vert signifie expédié et vérifié ; le rouge signifie un lancement non résolu et bloquant. Pour une présentation plus longue de chaque catégorie avec des extraits de code et des modèles d'échec réels, voir How to secure an app built with AI coding tools et The vibe coding security checklist.
Isolation des données clients
Dans un SaaS mutualisé, votre première limite de sécurité est l’isolation des données. Les données de chaque client doivent être inaccessibles à tous les autres clients, appliquées au niveau de la couche de base de données et non de la couche d'application.
- Activez la sécurité au niveau des lignes (RLS) sur chaque table Supabase avec
ALTER TABLE public.table_name ENABLE ROW LEVEL SECURITY; ALTER TABLE public.table_name FORCE ROW LEVEL SECURITY;. FORCE empêche le propriétaire de la table de la contourner. - Pour chaque stratégie RLS, vérifiez les étendues du prédicat pour l’utilisateur ou l’organisation authentifié. Exemple :
CREATE POLICY "users_see_own" ON public.items FOR SELECT USING (auth.uid() = user_id);. Testez avec un deuxième compte utilisateur pour confirmer que les données restent isolées. - Si vous utilisez Firebase / Firestore, les règles doivent correspondre à votre modèle de locataire. N'utilisez pas
allow read, write: if true;ou des règles de test limitées dans le temps. Utilisezallow read, write: if request.auth.uid == resource.data.owner_uid;ou une correspondance équivalente à l’échelle de l’organisation. - Utilisez des URL signées ou des jetons de courte durée pour accéder aux fichiers, jamais de compartiments publics. Supabase Stockage : définissez
ENABLE ROW LEVEL SECURITYsur la tableobjectset créez des stratégies qui limitent l'accès aux fichiers à l'utilisateur authentifié. Testez les téléchargements en tant qu'utilisateurs différents. - Sur votre couche API, chaque requête doit inclure
auth.uid()ou le contexte org-id. Chaque requête de base de données doit filtrer selon ce contexte. Exemple : nonSELECT * FROM items WHERE id = $1; toujoursSELECT * FROM items WHERE id = $1 AND user_id = auth.uid().
Facturation et paiement
L'intégration Stripe est le point où la confiance des clients rencontre la sécurité financière. Une mauvaise configuration signifie ici des paiements volés, des boucles de remboursement ou des revenus manquants.
- Utilisez live Stripe keys en production. Testez avec une clé de mode test distincte lors de la mise en scène. Ne passez jamais du mode test au mode direct sans une analyse finale en mode direct.
- Vérifiez la signature du webhook sur chaque événement entrant :
const event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);. Lancez si la signature échoue. Stockez le secret du webhook uniquement dans une variable d'environnement, jamais dans le code. - Implémentez l'idempotence sur les gestionnaires de webhooks à l'aide d'une table de base de données saisie par
event.id. Si le même webhook arrive deux fois (ce sera le cas), la deuxième exécution est une non-opération. Écrivez la ligne d'idempotence dans la même transaction que le changement d'état. - Sur
customer.subscription.updatedetcustomer.subscription.deleted, révoquez immédiatement l'accès. N'attendez pas un cron. Testez en annulant un abonnement dans Stripe Dashboard et en vérifiant que l'utilisateur est verrouillé dans les 5 secondes. - Stockez uniquement le Stripe client ID et l'abonnement ID dans votre base de données, jamais la carte complète ou la clé API. Récupérez l’état de l’abonnement en direct à partir de Stripe sur chaque limite d’authentification (chargement de page, appel API, vérification cron). Ne mettez pas en cache l’état de l’abonnement pendant plus d’une minute.
Authentification et sessions
L'authentification est la cible des attaquants de second ordre dans le SaaS. Un compte utilisateur est un vecteur de données et de moyens de paiement.
- Utilisez
supabase.auth.getUser()sur chaque itinéraire protégé, jamaisgetSession().getSession()lit un cookie non vérifié ;getUser()valide le JWT côté serveur. Dans Next.js :const { data: { user } } = await supabase.auth.getUser();avant de diffuser du contenu protégé. - Définissez
SameSite=Laxsur les cookies d'authentification (Supabase Auth le fait par défaut). Vérifiez dans DevTools → Application → Cookies. Si vous voyezSameSite=None, ajoutezsameSite: 'Lax'à votre configuration de session. - Activez MFA sur votre propre compte administrateur. Pour MFA destiné à l'utilisateur, testez-le de bout en bout avant le lancement : inscrivez-vous, inscrivez un appareil TOTP, déconnectez-vous, reconnectez-vous avec le jeton TOTP, vérifiez qu'il fonctionne.
- Les jetons Magic-link doivent expirer dans les 15 minutes. Les jetons de réinitialisation du mot de passe doivent expirer dans un délai d'une heure. Les jetons de session (JWTs) peuvent durer plus longtemps (24h-7j) mais doivent être validés à chaque utilisation. Vérifiez les paramètres par défaut de votre fournisseur d'authentification.
- Testez l'intégralité de la déconnexion : après qu'un utilisateur a cliqué sur la déconnexion, le navigateur supprime la session d'authentification, le serveur révoque tous les jetons et l'utilisateur ne peut pas accéder aux pages protégées. Dans Supabase : appelez
await supabase.auth.signOut()et vérifiez que le JWT n'est plus valide à la prochaine requête.
PII et conformité
Si vous collectez un e-mail, un nom, des informations de paiement ou tout autre PII, vous avez des obligations légales : minimisation des données, stockage sécurisé, suppression à la demande et préparation DPA.
- Rédigez et publiez une politique de confidentialité (non facultative, même pour les SaaS indépendants). Indiquez quelles données vous collectez, pourquoi, combien de temps vous les conservez et les droits des utilisateurs (accès, rectification, suppression). Utilisez un modèle de Termly ou similaire, mais personnalisez-le.
- Implémentez un point de terminaison de compte de suppression API qui purge PII de la base de données. Testez-le : créez un compte, ajoutez des données, supprimez le compte, vérifiez que les données ont disparu (utilisez l'inspection directe de la base de données).
- Pour la conformité GDPR / CCPA, répondez aux demandes des personnes concernées (accès / correction / suppression) dans un délai de 30 jours. Documentez votre processus. Si votre application est basée sur EU- ou dessert EU utilisateurs, un addendum de données Processing (DPA) avec Stripe, Supabase et tout processeur est requis.
- Cryptez les champs sensibles au repos (les mots de passe sont hachés par votre fournisseur d'authentification ; mais la tokenisation de carte de crédit, les clés API et les secrets doivent utiliser
pgcryptoou un coffre-fort externe). Ne stockez jamais les numéros de carte de crédit en texte brut (utilisez plutôt la tokenisation Stripe).
Disponibilité opérationnelle
La sécurité est continue. La réponse aux incidents, la surveillance et les runbooks commencent avant le premier jour.
- Configurez une page d'état (Statuspage.io, Uptime Robot ou un simple index.html). Les clients doivent savoir si vous rencontrez une panne. Mettez-le à jour à chaque incident.
- Avoir une rotation de garde documentée et testée. Qui se réveille à 2 heures du matin ? Qui a les clés de déploiement ? Qui peut révoquer un token compromis ? Documentez-le et effectuez un exercice d'incendie avant le lancement.
- Rédigez un runbook de réponse aux incidents de sécurité : que faire si un client signale une violation, si vous perdez une clé, si un service tombe en panne. Distribuez-le à votre équipe. Testez un scénario (e.g., simulez une fuite de clé) pour vérifier que le plan fonctionne.
- Les procédures de sauvegarde et de restauration doivent être testées et non théoriques. Pouvez-vous restaurer à partir de sauvegardes ? Chronométrez-le. Supabase : activez les sauvegardes automatisées (rétention de 7 jours en version gratuite, 30 jours en version payante). Testez une restauration sur un projet distinct tous les trimestres.
- Activez la journalisation d'audit pour les opérations privilégiées : Stripe connexions au tableau de bord, Supabase administrateur API appels, modifications du schéma de base de données, rapprochement des paiements. Outils : CloudTrail (AWS), Supabase journaux d'audit, extension PostgreSQL
pgaudit.
Surface d'attaque externe
Votre limite API est soumise à une analyse constante des attaquants. Verrouillez-le avant que le trafic malveillant n’arrive.
- Limitez le débit de chaque point de terminaison public. Exemple : 100 requêtes par minute par IP lors de l'inscription, 10 par minute lors de la réinitialisation du mot de passe. Utilisez Vercel KV, Redis ou similaire. Échec avec 429 (trop de demandes).
- Ajoutez CAPTCHA (hCaptcha ou reCAPTCHA) aux points de terminaison d'inscription et de réinitialisation du mot de passe pour vaincre les robots. Vérifiez le jeton côté serveur avant d'accepter la demande.
- Utilisez un WAF (pare-feu d'application Web) si disponible : Cloudflare, Vercel pare-feu d'application Web ou AWS WAF. Bloquez automatiquement les adresses IP et les modèles malveillants connus.
- Recherchez les points de terminaison API ouverts. Exécutez mensuellement une analyse passive FixVibe sur votre domaine de production. Examinez les résultats des routes de débogage exposées, de l'introspection GraphQL, des fuites de clé API ou de l'exposition de la configuration.
- Effectuez une rotation des informations d'identification (API clés, OAuth jetons, mots de passe de base de données) tous les trimestres. Documentez la procédure de rotation et automatisez-la si possible.
Observabilité et journalisation
Lorsque les choses tournent mal, les journaux constituent votre dossier médico-légal. Configurez-les dès le premier jour.
- Centralisez les journaux : Supabase Journaux, Vercel Journaux, journaux d'application et journaux d'authentification sur un seul tableau de bord (Datadog, LogRocket ou ELK auto-hébergé). Consultable, conservé pendant au moins 90 jours.
- Alerte sur les événements de sécurité : échecs de connexion répétés (usurpation de compte possible), utilisation inhabituelle de API (scraping possible), pics d'erreurs (attaque possible ou incident légitime). Définissez des seuils et des intégrations Slack.
- Émettez des journaux d'audit pour chaque opération privilégiée : modifications du rôle de l'utilisateur, création d'un nouveau compte administrateur, ajouts de modes de paiement, modifications de la portée des clés API. Stockez-les séparément des journaux d’application avec une conservation immuable.
Vérification finale
Avant de faire votre annonce, exécutez une analyse FixVibe complète et examinez les résultats avec un œil de sécurité.
- Exécutez une FixVibe Pro analyse active sur votre domaine de production. Configurez votre domaine pour les tests actifs (DNS TXT ou HTTP vérification des fichiers). Autorisez l’analyse et examinez chaque résultat, particulièrement critique et de haute gravité. Corrigez ou acceptez chacun explicitement.
- Activer les nouvelles analyses programmées : Pro plan → 3h, 6h, 12h ou quotidiennement. Unlimited forfait → 6h, 12h, quotidiennement, tous les 2 jours ou hebdomadaire. Associez-le aux vérifications active IDOR walking, SQL injection et reflected XSS sur votre domaine vérifié.
- Configurez les webhooks : connectez FixVibe à Slack ou par e-mail pour que les découvertes critiques déclenchent des alertes en temps réel. Voir /docs/webhooks pour la configuration.
- Effectuez une dernière révision manuelle du code en vous concentrant sur les pièges de /docs/security-guides/ai-generated-code-security-scanner : secrets dans les bundles, RLS/rules, limites d'authentification, CSP, placement du middleware. Utilisez le vibe coding security checklist comme modèle de révision.
Jour de lancement
Vous avez effacé la liste de contrôle. Déployez en toute confiance. Après le lancement, surveillez activement : vérifiez les résultats FixVibe quotidiennement pendant la première semaine, répondez aux alertes dans un délai d'une heure et maintenez le calendrier d'analyse en cours. Pour un guide de renforcement étape par étape avec des extraits de code, voir How to secure an app built with AI coding tools.
