18 août 2026

v0 : ce que le générateur ne sécurise pas pour toi

v0 excelle à un exercice précis : transformer une description ou une maquette en composants React soignés, accessibles, cohérents visuellement. C'est exactement pour ça qu'il crée un risque particulier — le résultat a l'air fini, alors que la sécurité de ce qui se passe derrière chaque formulaire n'a jamais été la question posée à l'outil.

Un composant fini n'est pas un backend sécurisé

v0 génère principalement du frontend. Quand un composant doit persister des données, deux chemins reviennent souvent : soit un appel direct au client Supabase depuis le composant React, soit une API route ajoutée après coup — parfois par toi, parfois en redemandant à l'IA de "connecter le formulaire à la base". Dans les deux cas, rien ne garantit que la question "qui a le droit de lire ou modifier cette ligne" a été posée : le composant s'affiche parfaitement, la donnée s'enregistre, tout a l'air de fonctionner — y compris quand n'importe quel visiteur non connecté peut faire le même appel :

// composant généré — l'appel fonctionne, RLS n'a jamais été vérifié
const { data } = await supabase
  .from('profiles')
  .update({ role: 'admin' })
  .eq('id', someId);

Sans policy RLS qui restreint réellement cette écriture au propriétaire de la ligne (ou à un rôle autorisé), cet appel réussit pour n'importe qui possédant la clé anon publique — donc pour n'importe quel visiteur.

CORS copié-collé sans y repenser

Quand une API route est ajoutée pour recevoir les données d'un composant v0, une configuration CORS permissive (Access-Control-Allow-Origin: *) traîne souvent des exemples utilisés pour le prototypage local et n'est jamais resserrée avant la mise en ligne. Sur une route qui ne fait que lire des données publiques, l'impact est nul. Sur une route qui renvoie des données liées à une session ou à un utilisateur, c'est une fuite potentielle vers n'importe quel autre site.

Le correctif

Traite chaque composant généré par v0 comme un frontend qui a besoin d'un backend pensé séparément — pas comme une fonctionnalité livrée clé en main. Pour chaque table touchée par un formulaire ou un appel Supabase :

ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;

CREATE POLICY "users_update_own_profile" ON profiles
  FOR UPDATE
  TO authenticated
  USING (auth.uid() = id)
  WITH CHECK (auth.uid() = id);

Et si une API route a été ajoutée à côté, remplace le wildcard par la liste explicite des origines qui doivent vraiment pouvoir l'appeler.

Détails sur les deux pièges : RLS Supabase désactivé ou mal configuré et CORS trop permissif.

Une interface v0 déjà connectée à une vraie base de données ? Scanne le site pour vérifier que ce qui a été branché derrière est réellement protégé.