Le blog

Par outil7 juillet 2026 · 5 min de lecture

Sécuriser une app v0 (Vercel) avant la mise en ligne

v0 génère du Next.js sur Vercel : tout ce qui est préfixé NEXT_PUBLIC_ part dans le navigateur. Comment sécuriser une app v0 sans exposer tes clés.

Sécuriser une app v0 (Vercel) avant la mise en ligne

v0 génère du Next.js propre, avec Tailwind et shadcn, et le déploie sur Vercel en deux clics. Le rendu est souvent le plus soigné des builders. Mais Next.js a sa propre règle piégeuse, cousine de celle de Vite : tout ce que tu préfixes NEXT_PUBLIC_ part dans le navigateur.

La bonne nouvelle, c'est que Next.js te donne un endroit propre pour ranger tes secrets, côté serveur. La mauvaise, c'est que quand une app est générée vite, l'appel à la base ou à une API se retrouve souvent dans un composant client, là où la clé doit forcément être exposée pour fonctionner. Voilà où ça coince sur v0, et comment vérifier avant de mettre en ligne.

Serveur ou navigateur : la distinction qui change tout sur Next.js

Next.js coupe ton app en deux mondes. Les composants serveur, qui s'exécutent chez Vercel et ne descendent jamais dans le navigateur. Et les composants client (ceux marqués "use client"), qui tournent dans le navigateur du visiteur, avec tout ce qu'ils contiennent.

Un secret rangé dans un composant serveur, une Route Handler ou une Server Action reste invisible. Le même secret utilisé dans un composant client se retrouve dans le bundle téléchargé. Quand v0 génère un formulaire ou un appel à ta base, il le pose parfois côté client pour que ça marche tout de suite. Si l'appel a besoin d'une clé, cette clé devient publique.

Le piège du préfixe NEXT_PUBLIC_

La règle Next.js est nette. NEXT_PUBLIC_MA_CLE est injectée dans le navigateur. MA_CLE sans préfixe reste côté serveur et n'est jamais exposée. Le préfixe est un choix, pas un hasard : il dit « cette valeur peut être publique ».

Le dérapage classique : pour qu'un appel fonctionne depuis un composant client, on préfixe la variable NEXT_PUBLIC_, et une clé qui aurait dû rester secrète part dans le bundle. La clé anon de Supabase en NEXT_PUBLIC_SUPABASE_ANON_KEY, c'est normal, elle est publique. Une NEXT_PUBLIC_...SERVICE_ROLE, une clé OpenAI ou une sk_live Stripe préfixée ainsi, c'est ta clé secrète publiée.

Comment vérifier : ouvre ton app v0 en ligne, clic droit, Inspecter, onglet Sources, et cherche service_role, sk_live, sk-, ou le nom de tes clés d'API. Si l'une apparaît, régénère-la (elle est compromise) et déplace l'appel qui l'utilise dans une Route Handler ou une Server Action, côté serveur, sans préfixe.

Ta base Supabase : la clé publique ne protège rien

v0 branche souvent Supabase ou Postgres. Et là, le sujet n'est plus le préfixe, c'est le verrou de la base. Ce n'est pas la clé anon qui protège tes lignes, c'est le RLS (Row Level Security). Tant qu'il est désactivé, la clé publique visible dans ton app suffit à lire toutes les tables.

Le geste manquant est le même que sur tous les builders : activer le RLS et poser une règle par table. J'explique le fond dans RLS désactivé : pourquoi ta base est lisible, et la vérif à la main dans voir si ta base Supabase est ouverte en deux minutes. Colmate, lui, ne teste jamais ta base : il repère la clé publique Supabase exposée côté client et te signale l'exposition probable à vérifier.

Ce que Vercel gère, et ce qu'il ne gère pas

Un point où v0 s'en sort mieux que les apps Vite : Next.js ne sert pas tes source maps au navigateur en production par défaut. Ton code d'origine reste donc moins souvent exposé qu'avec un build Vite mal configuré. Ce n'est pas une garantie, une option peut le réactiver, mais c'est un souci de moins par défaut.

Vercel pose aussi le HTTPS et l'en-tête HSTS sur ses domaines. Ce qu'il ne pose pas seul, c'est une vraie CSP (Content-Security-Policy) et les autres en-têtes. Ceux-là s'ajoutent dans next.config.js avec la fonction headers(), ou dans un vercel.json. Sans CSP, ton app reste ouverte à l'injection de scripts.

Est-ce que v0 sécurise mon app tout seul ?

Non. v0 te donne une base Next.js correcte et un déploiement propre sur Vercel, mais il ne décide pas à ta place si une clé est côté serveur ou côté client, il n'active pas le RLS de ta base, et il ne pose pas de CSP. Ces choix restent les tiens, et ce sont eux qui exposent ou protègent tes données.

C'est le même angle mort que sur les autres builders, avec chacun sa mécanique. Si tu jongles entre plusieurs outils, la trame vaut aussi pour Lovable, Bolt et Replit.

La version rapide

Colmate lit ce que ton app v0 expose déjà en ligne et te sort la liste en trente secondes : clés visibles, en-têtes manquants, exposition probable de la base, classées par gravité, avec le correctif prêt à coller dans ton IA. En lecture seule, sans accès à ton code, sans jamais toucher à tes données. Je regarde la porte depuis la rue, je n'entre pas.

Scanne ton app v0 avant de la mettre en ligne. Tu verras tout de suite ce qui reste ouvert.

FAQ

Une variable NEXT_PUBLIC_ est-elle visible par les visiteurs ?

Oui. Tout ce qui est préfixé NEXT_PUBLIC_ est injecté dans le bundle et téléchargé par le navigateur. La clé anon de Supabase peut l'être sans souci, elle est publique. Une clé secrète, jamais : retire le préfixe et déplace son usage dans une Route Handler ou une Server Action, côté serveur.

Mon app v0 est sur Vercel, elle est sécurisée par défaut ?

En partie. Vercel te donne le HTTPS, l'en-tête HSTS et ne sert pas tes source maps par défaut. Il ne verrouille pas ta base Supabase, ne cache pas une clé mal placée et ne pose pas de CSP. Ces trois points restent à faire dans ton code ou ta config, avant de considérer l'app comme prête.

Comment savoir si une clé est bien restée côté serveur ?

Le test le plus simple : ouvre ton app en ligne, DevTools, onglet Sources, et cherche la clé (ou son préfixe). Si tu la trouves dans les fichiers téléchargés, elle est côté client, donc exposée. Si tu ne la trouves pas, c'est bon signe, elle est probablement restée sur le serveur. Une clé secrète ne doit jamais apparaître dans cette recherche.

Le réflexe avant la mise en ligne

Avant de publier ton app v0, ouvre-la comme un visiteur et cherche tes clés dans le navigateur. Deux minutes qui t'évitent de publier un secret. Passe la checklist en un scan, ou reprends la checklist complète avant déploiement pour la faire point par point.