Livrer vite, c'est très bien, mais il y a une courte liste qui mérite un coup d'œil avant d'ouvrir ton app au monde. Rien de tout cela n'exige d'être expert en sécurité, et tout se vérifie de l'extérieur en quelques minutes. Ce guide passe chaque point en revue sous trois angles : pourquoi c'est important, comment le vérifier toi-même et comment le corriger, avec des exemples de configuration pour les stacks que les apps créées par IA utilisent le plus (Next.js sur Vercel, Supabase, Firebase). À la fin, tu as la version en deux minutes à coller dans ta liste de lancement.
Comment les attaquants trouvent tout ça en quelques minutes
La plupart des brèches dans les apps créées par IA ne sont pas des hacks ingénieux. Quelqu'un ouvre ton site, appuie sur F12, lit le JavaScript que ton app a déjà envoyé à son navigateur et copie une URL que ton app appelle déjà. Les scanners automatiques font pareil à grande échelle, en frappant des chemins courants comme /.env ou /.git sur des milliers de sites par jour sans même savoir que tu existes. Tout ce qui suit est quelque chose qu'ils peuvent vérifier sans aucun accès à ton code, et c'est exactement pour ça que tu dois le vérifier en premier.
1. Aucun secret dans le frontend
Pourquoi c'est important. Les clés d'API et les tokens n'ont leur place que sur le serveur. Quand un assistant IA « connecte » un service, il glisse souvent la clé directement dans le code client, où n'importe qui peut la lire dans les DevTools. Une clé Stripe sk_live_ qui fuit peut déplacer de l'argent réel ; une clé Supabase service_role livre toute ta base de données ; une clé OpenAI ou Anthropic te laisse payer la facture de quelqu'un d'autre.
Comment vérifier. Ouvre ton site, appuie sur F12 → onglet Sources (ou Network filtré sur JS) et cherche dans les fichiers des chaînes comme sk_live, service_role, AKIA, sk-ant, AIza ou -----BEGIN. Si ton framework utilise des variables à préfixe public (NEXT_PUBLIC_, VITE_, NUXT_PUBLIC_), assure-toi qu'aucune ne contient un secret : ce préfixe signifie littéralement « ceci part dans le navigateur ».
Comment corriger. Déplace chaque secret dans une variable d'environnement côté serveur et fais l'appel depuis une route d'API ou une fonction serverless ; le navigateur parle à ton serveur, jamais au fournisseur. Et fais tourner la clé qui a fui : une fois qu'elle a été dans un bundle public, considère-la comme compromise même après l'avoir retirée. Plus de détails dans les secrets que ton app laisse fuir dans le navigateur.
2. HTTPS et en-têtes de sécurité
Pourquoi c'est important. Sers tout en HTTPS et redirige le HTTP vers lui, pour que personne ne puisse lire ni altérer le trafic. Ajoute ensuite les en-têtes que les navigateurs utilisent pour défendre tes utilisateurs : Content-Security-Policy pour contenir les injections, Strict-Transport-Security pour verrouiller le HTTPS, X-Frame-Options pour bloquer le clickjacking et X-Content-Type-Options pour empêcher le navigateur de « deviner » les types de fichiers. La plupart des apps générées sortent sans aucun d'eux par défaut.
Comment vérifier. Interroge ton site avec curl -I https://tondomaine.com et regarde les en-têtes qui reviennent, ou utilise le vérificateur gratuit d'en-têtes de sécurité.
Comment corriger. Dans Next.js, tu les déclares dans next.config.js ; sur Vercel, pour n'importe quel framework, dans vercel.json :
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "Strict-Transport-Security", "value": "max-age=31536000; includeSubDomains" },
{ "key": "X-Frame-Options", "value": "SAMEORIGIN" },
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
{ "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }
]
}
]
}
La CSP mérite un moment à part : commence en mode Content-Security-Policy-Report-Only, regarde ce qu'elle bloquerait et passe-la en mode strict quand elle ne casse plus rien. Voir les en-têtes de sécurité HTTP expliqués.
3. Des règles de base de données (RLS) sur chaque table
Pourquoi c'est important. Si tu utilises Supabase ou Firebase, ton app parle à la base de données directement depuis le navigateur, donc les règles de la base sont la seule chose entre un visiteur et tes données. Sans elles, n'importe qui disposant de la clé publique lit et écrit dans tes tables sans se connecter : exactement la faille derrière la vulnérabilité RLS de Lovable.
Comment vérifier. Avec l'app ouverte, copie un appel /rest/v1/ depuis l'onglet Network et ouvre-le dans une fenêtre de navigation privée. S'il renvoie des données sans session, tu es exposé. Dans Supabase, le Table Editor signale les tables avec un badge rouge « RLS disabled ». Dans Firebase, vérifie que les règles ne sont pas restées en mode test (allow read, write: if true ou avec une date d'expiration).
Comment corriger. Active le Row-Level Security sur chaque table avec une politique de refus par défaut et écris des règles par opération liées à l'utilisateur. Dans Supabase, le minimum pour une table avec une colonne user_id :
alter table public.items enable row level security;
create policy "items: ses propres lignes uniquement" on public.items
for all to authenticated
using ((select auth.uid()) = user_id)
with check ((select auth.uid()) = user_id);
Et ne compte jamais sur un bouton caché dans l'interface : la requête existe toujours.
4. Aucun fichier sensible exposé
Pourquoi c'est important. Une seule requête vers /.env peut livrer tous les secrets que ton app utilise ; /.git/config permet à n'importe qui de télécharger tout ton dépôt ; des source maps publiées lui permettent de reconstruire ton code d'origine ; un backup.sql oublié, c'est ta base de données dans un fichier.
Comment vérifier. Essaie tondomaine.com/.env, /.git/HEAD, /.DS_Store, /backup.sql dans le navigateur, et ouvre un fichier JS de ton bundle pour voir s'il se termine par une ligne //# sourceMappingURL= pointant vers un .map accessible. Sur des plateformes comme Vercel ou Netlify, le .env n'est jamais déployé, mais sur un VPS avec nginx ou Apache, ça arrive.
Comment corriger. Bloque les dotfiles sur le serveur (dans nginx, location ~ /\. { deny all; }), désactive les source maps en production (productionBrowserSourceMaps: false dans Next.js, build.sourcemap: false dans Vite) et sors les sauvegardes du dossier public.
5. Un CORS verrouillé
Pourquoi c'est important. Une politique CORS qui reflète n'importe quelle origine avec identifiants permet à un site malveillant de lire les données de tes utilisateurs en utilisant leur session. Access-Control-Allow-Origin: * sans identifiants est inoffensif pour des données publiques ; le danger, c'est de renvoyer l'origine qui demande, quelle qu'elle soit, et d'ajouter Access-Control-Allow-Credentials: true.
Comment vérifier. Interroge l'un de tes endpoints d'API avec curl -I -H "Origin: https://evil.example" https://tondomaine.com/api/nimportequoi. Si la réponse renvoie cette même origine dans Access-Control-Allow-Origin plus Allow-Credentials: true, tu as le problème.
Comment corriger. Garde une liste fermée d'origines autorisées (tes domaines de production et, au maximum, celui de preview) et compare avec elle ; toute autre origine ne reçoit aucun en-tête.
6. Des cookies et des sessions bien configurés
Pourquoi c'est important. Les cookies de session doivent porter Secure (HTTPS uniquement), HttpOnly (illisibles depuis JavaScript, pour qu'un XSS ne puisse pas les voler) et SameSite=Lax ou Strict (défend contre le CSRF). C'est une ligne de configuration et ça ferme toute une classe de bugs de vol de compte.
Comment vérifier. F12 → Application → Cookies et regarde les colonnes Secure, HttpOnly et SameSite de ton cookie de session. Si tu utilises un fournisseur d'auth (Supabase Auth, Clerk, NextAuth), ils sortent en général corrects ; ceux qui échouent sont les cookies que ta propre app ajoute.
Comment corriger. En posant le cookie : Set-Cookie: session=…; Secure; HttpOnly; SameSite=Lax; Path=/. Dans Express, res.cookie(name, value, { secure: true, httpOnly: true, sameSite: 'lax' }).
7. Des dépendances avec des vulnérabilités connues
Pourquoi c'est important. Ton app traîne des centaines de paquets. Une version vulnérable d'une bibliothèque qui analyse des entrées utilisateur est une porte d'entrée que tu n'as pas écrite mais qui est quand même la tienne.
Comment vérifier et corriger. Lance npm audit dans le projet et règle d'abord les résultats critiques et élevés ; active Dependabot ou Renovate sur le dépôt pour que les correctifs viennent à toi. Si ton site expose un package.json public, tu annonces aussi tes versions.
8. Des limites de débit sur les endpoints qui coûtent de l'argent ou ouvrent des portes
Pourquoi c'est important. Le formulaire de connexion, l'inscription, l'envoi d'emails et tout endpoint qui appelle une API d'IA payante ont besoin d'une limite par IP ou par compte. Sans ça, un script essaie des milliers de mots de passe ou fait grimper une facture de tokens pendant la nuit.
Comment corriger. Une limite de débit simple côté serveur (par IP et par minute) et, chez les fournisseurs payants, un plafond de dépenses configuré dans leur tableau de bord. Les fournisseurs d'auth livrent en général des limites de tentatives déjà actives : vérifie que tu ne les as pas désactivées.
9. Des erreurs qui n'en disent pas trop
Pourquoi c'est important. Une page d'erreur avec la stack trace complète, la requête SQL ou le chemin du serveur est une carte pour celui qui attaque. Il en va de même pour des en-têtes comme X-Powered-By qui annoncent des versions exactes.
Comment corriger. Des pages d'erreur génériques en production, avec le détail uniquement dans tes logs. Retire X-Powered-By (dans Next.js, poweredByHeader: false).
10. Un domaine et un email prêts pour de vrais utilisateurs
Pourquoi c'est important. Si tu envoies des emails (confirmations, réinitialisations de mot de passe), sans SPF, DKIM et DMARC ils finiront en spam ou, pire, n'importe qui pourra envoyer des mails en se faisant passer pour ton domaine. Et un certificat ou un domaine qui expire fait tomber tout le site.
Comment vérifier et corriger. Publie des enregistrements SPF et DMARC dans le DNS, active DKIM chez ton fournisseur d'envoi et active le renouvellement automatique du domaine et du certificat. Une demi-heure de travail qui évite la pire journée possible.
Dans quel ordre corriger si tu as une heure
- D'abord, les secrets dans le frontend et les règles de base de données : les deux failles qui livrent de vraies données à n'importe qui.
- Ensuite, les fichiers exposés et le CORS : peu coûteux à corriger et très sondés par les scanners automatiques.
- Puis, les en-têtes, les cookies et les pages d'erreur : ils durcissent ce qui fonctionne déjà.
- Enfin, les dépendances, les limites de débit et l'email : moins urgents le jour du lancement, essentiels la semaine d'après.
Ta checklist de 2 minutes avant de lancer
- Aucune clé
sk_live_,service_roleou clé privée dans ton JavaScript ; variables publiques passées en revue. - HTTPS forcé, avec HSTS, X-Frame-Options, X-Content-Type-Options et une CSP au moins en mode rapport.
- Row-Level Security (ou règles Firebase) sur chaque table ; le test en navigation privée renvoie vide.
.env,.git, sauvegardes et source maps inaccessibles.- CORS limité à tes propres origines, sans jamais renvoyer l'origine avec identifiants.
- Cookies avec Secure, HttpOnly et SameSite.
npm auditsans résultats critiques ni élevés.- Limites de tentatives sur la connexion, l'inscription et les endpoints d'IA ; plafonds de dépenses chez les fournisseurs.
- Pages d'erreur sans traces ; pas de
X-Powered-By. - SPF, DKIM et DMARC publiés ; renouvellement automatique du domaine et du certificat.
Règle ça une bonne fois pour toutes
Au lieu de tout vérifier à la main, lance Scanaris : il vérifie ces points et une quarantaine d'autres sur ton site en ligne en 30 secondes, classe les résultats par impact et te donne un prompt prêt à coller pour corriger chacun avec ton IA, avant que quelqu'un d'autre ne les trouve. Active la surveillance et il te prévient quand quelque chose de cette liste se casse à nouveau après le lancement.
Questions fréquentes
Est-ce que ça remplace un audit de sécurité professionnel ?
Non. Cette liste couvre ce qui peut être vérifié de l'extérieur et ce qui échoue dans presque toutes les apps créées par IA. Un audit examine aussi ta logique métier, les permissions entre utilisateurs et le code lui-même. Mais sans cette liste, l'audit commencerait par les mêmes points.
Combien de temps prend tout ça ?
Vérifier : dix minutes avec un scanner ou une demi-heure à la main. Corriger : entre un après-midi et une journée selon le nombre de points qui échouent ; les secrets et le RLS prennent le plus de temps parce qu'ils t'obligent à déplacer du code vers le serveur.
Et après le lancement ?
Refais la liste chaque fois que l'IA génère une nouvelle fonctionnalité qui touche à des données ou à des clés, et mets en place un re-scan automatique hebdomadaire : les apps se cassent à cause des changements, pas à cause du temps.