PROMPTACADEMY
REJOINDRE
SÉCURITÉ

Sécuriser ton app vibecodée avant de la mettre en ligne

45% du code généré par IA contient une faille de sécurité. Voici la checklist pour pas faire partie des apps qui leakent les données de leurs users.

Par Mario, Fondateur Prompt Academy · 11 min de lecture · Gratuit, sans compte

L'IA code vite. Mais elle code pas sécurisé.

Une étude Veracode de 2025 a testé plus de 100 modèles d'IA. Le résultat : 45% du code généré contient une faille de sécurité du top 10 OWASP. Presque une chance sur deux.

Et c'est pas un cas isolé. Escape Tech a scanné 5 600 apps vibecodées. Le bilan : plus de 2 000 vulnérabilités, plus de 400 secrets exposés — clés API, tokens — et 175 fuites de données perso.

Un exemple concret ? L'app Moltbook a exposé 1,5 million de tokens d'authentification. La cause : une seule chose oubliée, le RLS. On y revient plus bas.

C'est pas de la parano. C'est ce qui se déploie en ce moment, partout. La bonne nouvelle : 90% de ces fuites viennent de quelques erreurs basiques. Celles qu'on va checker ensemble, une par une.

Comment utiliser cette checklist

Chaque point est classé par niveau de criticité. Tu traites dans l'ordre.

  • 🔴 Critique : si c'est pas coché, tu déploies pas. Point.
  • 🟠 Important : à régler avant d'avoir de vrais utilisateurs.
  • 🟡 Recommandé : bonnes pratiques à appliquer vite.

Une précision honnête : cette liste n'est pas exhaustive. C'est le minimum vital, pas un audit de sécurité complet. Si tu coches tout, tu as éliminé les catastrophes les plus courantes. Pour aller plus loin, d'autres ressources arriveront.

Secrets & clés API

Le secret exposé, c'est LA fuite numéro un. Dans l'étude Escape Tech, plus de 400 apps avaient leurs clés en clair. Une clé API exposée, c'est simple : quelqu'un peut utiliser ton compte, cramer ton quota, accéder à tes données.

Critique — Ne déploie pas sans ça
Secrets & clés API
Ton fichier .env est dans .gitignore AVANT ton premier commit
Si tu commit .env une fois, la clé reste dans l'historique Git même si tu la supprimes après. Ajoute .env au .gitignore dès le début.
Aucune clé API en dur dans le code
Jamais de clé écrite directement dans un fichier .ts ou .js. Toujours via une variable d'environnement (process.env).
Tu connais la différence entre clé publique et clé secrète
Sur Supabase : la anon key peut aller côté client (le navigateur). La service_role key bypass toute la sécurité RLS — elle reste UNIQUEMENT côté serveur, jamais dans le code frontend.
Ton bundle frontend ne contient aucun secret
Ouvre les DevTools de ton navigateur, onglet Sources, et cherche tes clés. Si une clé secrète apparaît, elle est publique. Tout ce qui est dans le code client est visible par tout le monde.
Si une clé a fuité, tu l'as révoquée et régénérée
Une clé exposée même 5 minutes est compromise. Va dans ton dashboard (Supabase, Stripe, etc.), révoque-la, génère-en une nouvelle.

Base de données & RLS

Le RLS — Row Level Security — c'est ce qui empêche l'utilisateur A de lire les données de l'utilisateur B. C'est LE truc que les vibecoders oublient. L'app Moltbook a leaké 1,5 million de tokens juste pour ça. Sur Supabase, sans RLS, n'importe qui avec ta anon key peut lire toute ta base.

Critique — Ne déploie pas sans ça
Base de données & RLS
Le RLS est activé sur TOUTES les tables de ton schéma public
Sur Supabase, une table sans RLS dans le schéma public est lisible et modifiable par n'importe qui via l'API. Active le RLS sur chaque table, sans exception. Le service_role bypass le RLS volontairement, pour les opérations admin côté serveur.
Chaque table a des policies (RLS activé sans policy = tout bloqué)
Activer le RLS sans créer de policy bloque tout accès. Tu dois définir qui peut faire quoi : SELECT, INSERT, UPDATE, DELETE.
Tes policies utilisent auth.uid(), pas les métadonnées du user
Base tes règles sur auth.uid() (l'identifiant vérifié de l'utilisateur). N'utilise jamais user_metadata dans une policy : c'est modifiable par l'utilisateur lui-même, donc contournable.
Tes policies INSERT et UPDATE ont un WITH CHECK
Sans WITH CHECK, un user peut insérer ou modifier une ligne en se faisant passer pour un autre (en mettant l'user_id de quelqu'un d'autre). Le WITH CHECK vérifie que la nouvelle donnée respecte bien la règle.
Tu as testé avec 2 comptes différents
Crée deux comptes. Connecte-toi avec le compte A, essaie d'accéder aux données du compte B. Si tu y arrives, ton RLS est cassé. C'est le test le plus simple et le plus important.
Tu sais que le SQL Editor de Supabase bypass le RLS
Le SQL Editor s'exécute en superadmin : il voit tout, même avec le RLS activé. Pour tester tes policies, passe par ton app (le client SDK) avec un vrai compte connecté, pas depuis le SQL Editor.

Authentification & accès

Une page « protégée » qui vérifie l'accès seulement côté client, c'est une porte fermée avec la clé sous le paillasson. La vérification doit se faire côté serveur.

Important — À régler avant tes premiers utilisateurs
Authentification & accès
Tes pages protégées vérifient l'accès côté serveur
Cacher un bouton ou rediriger en JavaScript côté client ne protège rien : ça se contourne. La vérification doit se faire côté serveur (middleware, server component, ou route handler).
Tu vérifies les permissions à chaque requête sensible, pas juste au login
Un user banni ou dont l'abonnement a expiré doit être bloqué en temps réel, pas seulement au moment de la connexion.
Le logout invalide vraiment la session
Après déconnexion, l'ancien token ne doit plus donner accès à rien.
Tes mots de passe ont des règles minimales
Longueur minimum, et idéalement une vérification contre les mots de passe les plus courants. La plupart des solutions d'auth (comme Supabase Auth) gèrent ça — ne réinvente pas le hashage toi-même.

Injections & validation des entrées

Tout ce que l'utilisateur tape peut être une attaque. Le XSS (Cross-Site Scripting) avait un taux d'échec de 86% dans le test Veracode sur le code IA. La règle tient en une phrase : ne fais jamais confiance à une entrée utilisateur.

Important — À régler avant tes premiers utilisateurs
Injections & validation des entrées
Tu utilises des requêtes paramétrées, jamais de concaténation SQL
Ne construis jamais une requête SQL en collant directement du texte tapé par l'utilisateur. Utilise les requêtes paramétrées ou un ORM. Sinon, injection SQL = accès à toute ta base.
Tu valides les entrées côté serveur, pas juste côté client
La validation dans le navigateur, c'est du confort pour l'utilisateur. La vraie validation (celle qui protège) se fait côté serveur, parce que le client est contournable.
Tu n'injectes pas de contenu user dans du HTML brut
Évite dangerouslySetInnerHTML (React) avec du contenu venant des utilisateurs. C'est la porte ouverte au XSS : un user peut injecter du script qui s'exécute chez les autres.
Tu n'utilises pas eval() ou équivalent sur des entrées user
Exécuter du code à partir de texte fourni par l'utilisateur = exécution de code arbitraire. À bannir.

Réseau & déploiement

Ces réglages, c'est la base d'un déploiement propre. Pas le plus sexy, mais ça ferme plein de petites portes.

Recommandé — Bonnes pratiques à appliquer vite
Réseau & déploiement
Ton site est en HTTPS
En prod, jamais de HTTP nu. La plupart des hébergeurs (Vercel, etc.) le forcent automatiquement. Vérifie quand même.
Ton CORS est restreint, pas ouvert à tous
Ne mets pas Access-Control-Allow-Origin à l'étoile (*) si ton API gère des données sensibles. Limite aux domaines que tu contrôles.
Tes erreurs n'affichent pas de détails techniques aux utilisateurs
Une stack trace ou un message d'erreur de base de données affiché à l'écran donne des infos aux attaquants. En prod, montre un message générique, log le détail côté serveur.
Tu as des headers de sécurité (CSP, HSTS, X-Frame-Options)
Ces en-têtes HTTP protègent contre plusieurs attaques (injection de contenu, clickjacking). Next.js permet de les configurer facilement.
Tu as du rate limiting sur les routes sensibles
Limite le nombre de tentatives sur le login, le signup, les paiements. Sans ça, quelqu'un peut tester des milliers de mots de passe ou spammer tes endpoints.

Dépendances

Le code que tu installes peut être vérolé. Et l'IA invente parfois des noms de packages qui n'existent pas. Des attaquants créent ces faux packages exprès — ça s'appelle le slopsquatting.

Recommandé — Bonnes pratiques à appliquer vite
Dépendances
Tu lances npm audit avant de déployer
npm audit liste les failles connues dans tes dépendances. Fais-le régulièrement, et avant chaque déploiement important.
Tu vérifies les packages que l'IA te suggère d'installer
L'IA hallucine parfois des noms de packages qui n'existent pas. Des attaquants créent ces faux packages avec du code malveillant. Avant d'installer un package suggéré par l'IA, vérifie qu'il est légitime : téléchargements, dépôt GitHub, popularité.
Tu n'ajoutes pas de dépendance sans savoir ce qu'elle fait
Chaque package ajouté, c'est du code tiers qui tourne chez toi. Moins tu en as, mieux c'est.

Avant de déployer

Récapitulons.

Si tu coches au minimum tout le 🔴 critique, tu as déjà éliminé les fuites les plus graves — celles qui font les gros titres. Le 🟠 important, c'est pour quand tu as de vrais utilisateurs. Le 🟡 recommandé, c'est la finition pro.

Et encore une fois : c'est une base, pas un audit complet. Mais une base solide vaut mieux qu'un audit que tu feras jamais.