← Retour au blog
Vibe codingScanaris Team · 6 min de lecture · October 04, 2026

La sécurité lors du déploiement sur Vercel

Vercel rend le déploiement si facile qu'on oublie que ça reste un serveur sur internet. La plateforme elle-même est bien protégée : TLS automatique, réseau mondial, isolation entre projets. Les trous, c'est toi qui les mets dans la configuration, et ce sont presque toujours les mêmes cinq ou six. Ce guide les passe en revue un par un avec la commande pour les vérifier et le changement exact pour les fermer, en pensant aux applis générées avec Cursor, Bolt ou v0 qui finissent sur Vercel.

1. Des variables d'environnement qui finissent dans le navigateur

Sur Vercel, tu définis les variables dans le panneau du projet, et le framework décide lesquelles arrivent au client. En Next.js, tout ce qui commence par NEXT_PUBLIC_ ; en Vite, par VITE_ ; en Nuxt, ce qui est sous runtimeConfig.public. C'est une convention utile jusqu'à ce que quelqu'un mette NEXT_PUBLIC_STRIPE_SECRET_KEY parce que l'IA avait besoin d'y accéder depuis un composant. Cette clé voyage dans le bundle vers tous les visiteurs.

Deux habitudes l'évitent. D'abord, vérifier le préfixe : si une variable a le préfixe public, pars du principe qu'elle est publique et demande-toi si elle devrait l'être. Ensuite, utiliser les environnements de Vercel (Production, Preview, Development) pour que les clés de production n'existent pas sur les branches de test, et marquer les sensibles comme Sensitive, ce qui empêche de les voir ensuite depuis le panneau. Pour vérifier ce qui est arrivé dans le bundle :

curl -s https://tondomaine.com/ | grep -o '/_next/static/chunks/[^"]*\.js' | sort -u | head -20

Télécharge ces fichiers et cherche sk_live, service_role, AKIA ou le nom de tes variables. Plus dans les secrets que ton appli laisse fuiter dans le navigateur.

2. Des déploiements de prévisualisation publics

Chaque branche et chaque pull request génère une URL du type projet-git-branche-equipe.vercel.app. C'est pratique pour montrer des changements, et c'est public : n'importe qui avec l'URL voit la version en développement, avec ses fonctionnalités à moitié faites et, parfois, ses données de test. Vercel ajoute par défaut un en-tête pour que les moteurs de recherche n'indexent pas les prévisualisations, mais ça n'empêche pas une personne de l'ouvrir.

La solution est dans Settings, Deployment Protection : active Vercel Authentication pour que seuls les membres de l'équipe accèdent aux previews (disponible sur le plan gratuit), ou la protection par mot de passe sur les plans payants. Et souviens-toi que l'URL projet.vercel.app de production existe aussi à côté de ton domaine : redirige-la vers ton domaine ou pose une canonique pour qu'elle ne te fasse pas concurrence sur Google.

3. Des en-têtes de sécurité que personne n'a posés

Vercel sert ton appli avec les en-têtes minimaux ; ceux de sécurité, c'est à toi de les ajouter. Sans eux, ton site peut être intégré dans un iframe étranger, le navigateur devine les types de contenu et il n'y a pas de politique qui limite quels scripts s'exécutent. Dans vercel.json, ça s'ajoute comme ça :

{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        { "key": "Strict-Transport-Security", "value": "max-age=63072000; includeSubDomains; preload" },
        { "key": "X-Content-Type-Options", "value": "nosniff" },
        { "key": "X-Frame-Options", "value": "DENY" },
        { "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
        { "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }
      ]
    }
  ]
}

En Next.js, tu peux aussi le faire depuis next.config.js avec la fonction headers(). La Content-Security-Policy mérite une étape à part parce qu'il faut l'ajuster à tes scripts ; l'explication de chaque en-tête est dans les en-têtes de sécurité HTTP expliqués pour les humains, et tu peux vérifier les tiens avec l'analyseur d'en-têtes.

4. Des source maps publiées

Les source maps permettent de voir le code original au lieu du code minifié. Elles sont utiles pour déboguer et une mauvaise idée en production : elles offrent ta logique, tes routes internes et les commentaires avec « TODO : retirer cette clé ». Next.js les désactive par défaut dans le navigateur (productionBrowserSourceMaps: false) ; en Vite, ça dépend de build.sourcemap, que certains templates mettent à true. Vérifie si elles existent :

curl -sI https://tondomaine.com/_next/static/chunks/main-abc123.js.map | head -1

Si ça répond 200, elles sont publiées. Si tu as besoin de maps pour suivre les erreurs, envoie-les à ton service de monitoring au build et ne les sers pas au public.

5. Des fichiers et des routes qui ne devraient pas répondre

Tout ce qui est dans le dossier public/ est servi tel quel. Un .env copié là par erreur, un backup.json, un config.yml avec des identifiants : publics. Les routes d'API comptent aussi : /api/debug, /api/seed ou /api/admin que l'IA a créées pour tester et qui sont toujours en production sans authentification. Et les routes de cron : Vercel les appelle avec un en-tête Authorization qui contient ton CRON_SECRET ; si tu ne le vérifies pas dans le code, n'importe qui peut lancer ta tâche planifiée.

for p in .env .env.local .git/config config.json backup.zip api/debug api/seed; do
  printf "%s -> " "$p"; curl -s -o /dev/null -w "%{http_code}\n" "https://tondomaine.com/$p"
done

Tout ce qui répond 200 mérite un coup d'œil.

6. Des fonctions sans limites

Une route d'API qui appelle OpenAI ou envoie des e-mails sans limiter les requêtes, c'est une facture qui attend d'être découverte. Vercel a un pare-feu avec des règles de limitation de requêtes par IP et un mode de défi contre les bots qui s'active depuis le panneau sans toucher au code. Pour les endpoints qui coûtent, ajoute en plus une limite par utilisateur dans ta propre logique et exige une session.

7. CORS et cookies sur les routes d'API

Si ton API répond avec Access-Control-Allow-Origin: * et utilise en plus des cookies, n'importe quel site peut faire des requêtes au nom de tes utilisateurs. Sur Vercel, ça se configure par route dans vercel.json ou dans le handler lui-même. Liste les origines autorisées explicitement et ne combine jamais le joker avec des identifiants. Le détail dans CORS mal configuré.

8. Ce que Vercel fait déjà pour toi

Pour que tu ne perdes pas de temps : le certificat TLS est émis et renouvelé tout seul, HTTP redirige vers HTTPS automatiquement, les fonctions tournent isolées et les journaux de déploiement sont audités. Ce qu'il ne fait pas, c'est décider à ta place ce qui est public, quels en-têtes tu envoies ni qui peut voir tes previews. Cette partie-là est à toi.

Checklist de cinq minutes

  • Aucune variable avec préfixe public ne contient une clé secrète.
  • Deployment Protection activée pour les prévisualisations.
  • En-têtes de sécurité dans vercel.json ou next.config.js.
  • Source maps inaccessibles en production.
  • Rien de sensible dans public/ ; routes de test supprimées ; cron protégé par son secret.
  • Limitation de requêtes sur les routes qui coûtent.
  • CORS avec des origines explicites.
  • L'URL .vercel.app redirige vers ton domaine.

Scanaris le vérifie pour toi

Scanaris contrôle de l'extérieur ton déploiement sur Vercel : en-têtes, secrets dans le bundle, source maps, fichiers et routes exposés, CORS, cookies et TLS, et te donne un fix prompt pour chaque défaut à coller dans Cursor, Bolt ou v0 avec le changement exact dans vercel.json ou dans ton code. Ce sont des vérifications en lecture seule sur ce qui est déjà public ; il ne touche jamais à ton projet. Les risques propres à la plateforme sont dans le guide de sécurité pour Vercel, et si ton appli est en Next.js, dans la checklist Next.js.

Questions fréquentes

Les prévisualisations Vercel sont-elles privées par défaut ?

Non. Elles sont publiques pour qui a l'URL, même si elles ne sont pas indexées par les moteurs de recherche. Active Vercel Authentication dans Deployment Protection pour les limiter à ton équipe.

Vercel pose-t-il des en-têtes de sécurité automatiquement ?

Seulement les en-têtes de base nécessaires au fonctionnement. HSTS, X-Frame-Options, Content-Security-Policy et les autres, c'est à toi de les configurer dans vercel.json ou dans le framework.

Que se passe-t-il si une clé secrète a déjà été publiée avec un préfixe public ?

Considère-la comme compromise même si tu la retires du code : le bundle précédent peut être en cache ou téléchargé. Fais tourner la clé chez le service d'origine, déplace-la dans une variable sans préfixe et redéploie.

Comment se porte ton site ?

Passe-lui Scanaris et vérifie en 30 secondes, c'est gratuit.

Analyser mon site

Vérifications liées

Guides de sécurité par stack