← Retour au blog
SécuritéScanaris Team · 8 min de lecture · October 04, 2026

Checklist de sécurité pour ton appli Next.js avant le lancement

Lancer une app Next.js avec Cursor, v0 ou Bolt va vite, mais la vitesse cache des failles que tu ne vois pas tant que quelqu'un ne les trouve pas à ta place. Cette checklist passe en revue ce qu'il faut vérifier avant d'appuyer sur deploy, avec le pourquoi de chaque point, comment le vérifier et le code pour le corriger. La version en deux minutes est à la fin.

Comment Next.js trace la frontière entre serveur et client

Presque toutes les failles de sécurité dans Next.js sont la même faille : quelque chose qui devait rester sur le serveur est passé dans le navigateur. Les Server Components s'exécutent sur le serveur et n'envoient jamais leur code au client ; dès qu'un fichier porte 'use client', tout ce qu'il importe finit dans le bundle public. Les Route Handlers (app/api/*/route.ts) et les Server Actions sont des URL publiques même si tu ne les vois pas. Le middleware tourne avant tout le reste, mais ce n'est pas une muraille. Une fois cette frontière claire, le reste de la liste est mécanique.

1. Variables d'environnement : attention à NEXT_PUBLIC

Pourquoi c'est important. Tout ce qui commence par NEXT_PUBLIC_ est intégré au JavaScript du navigateur au moment du build. N'importe qui peut le lire avec les outils de développement. N'y mets jamais une clé d'API privée, un token de service ni le secret de ta base de données.

Comment vérifier. Ouvre ton .env et ton tableau de bord Vercel et lis chaque variable à préfixe public en te demandant : se passerait-il quelque chose si je la publiais sur Twitter ? Si la réponse est oui, retire le préfixe et déplace-la côté serveur.

Comment corriger. Les variables sans préfixe n'existent que sur le serveur : lis-les depuis des Server Components, des Route Handlers ou des Server Actions. Pour qu'un module contenant des secrets ne puisse jamais être importé depuis un composant client, ajoute import 'server-only' en première ligne : si quelqu'un l'importe du mauvais côté, le build échoue au lieu de laisser fuir la clé. Plus de détails dans les secrets que ton app laisse fuir dans le navigateur.

2. Route Handlers et Server Actions : toujours valider et autoriser

Pourquoi c'est important. Une route d'API n'est pas privée parce qu'elle est dans ton dossier. C'est une URL publique que n'importe qui peut appeler avec curl. Et une Server Action, même invoquée depuis un bouton, aussi : Next.js l'expose comme un endpoint POST avec un identifiant. Un bouton caché à un utilisateur n'empêche personne de frapper l'endpoint directement.

Comment corriger. Vérifie la session et les permissions dans chaque handler et chaque action, pas seulement dans l'interface. Valide le corps de la requête avec un schéma (zod ou similaire) avant de toucher à la base de données. N'accepte jamais l'identifiant de l'utilisateur depuis le client : prends-le dans la session. Et limite le débit de tout ce qui coûte de l'argent ou envoie des emails.

// app/actions/update-profile.ts
'use server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'

const Schema = z.object({ name: z.string().min(1).max(80) })

export async function updateProfile(input: unknown) {
  const session = await getSession()
  if (!session) throw new Error('Unauthorized')
  const data = Schema.parse(input)
  // utilise session.user.id, jamais un id venu du client
  await db.user.update({ where: { id: session.user.id }, data })
}

3. Le middleware n'est pas ta seule authentification

Pourquoi c'est important. Il est tentant de protéger tout /dashboard depuis middleware.ts et de ne plus y penser. En mars 2025 a été publiée la CVE-2025-29927 : un en-tête interne (x-middleware-subrequest) permettait de contourner complètement le middleware sur les versions touchées, et avec lui toute vérification de session qui ne vivait que là. Elle a été corrigée dans Next.js 15.2.3 et 14.2.25 (avec des correctifs pour 13 et 12), mais la leçon reste.

Comment corriger. Mets Next.js à jour vers une version corrigée et utilise le middleware comme première couche (rediriger qui n'a pas de session), jamais comme la seule. La vérification qui protège vraiment les données va dans la page, le handler ou l'action qui les sert.

4. En-têtes de sécurité

Pourquoi c'est important. Par défaut, Next.js n'envoie aucun en-tête défensif. Sans eux, ton app est exposée au clickjacking, à l'exécution par le navigateur de ce qui n'est pas un script et au downgrade vers HTTP.

Comment corriger. Dans next.config.js :

// next.config.js
const securityHeaders = [
  { 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=()' },
]

module.exports = {
  poweredByHeader: false,
  productionBrowserSourceMaps: false,
  async headers() {
    return [{ source: '/(.*)', headers: securityHeaders }]
  },
}

La Content-Security-Policy mérite un traitement à part : Next.js injecte des scripts inline pour hydrater la page, donc une CSP stricte a besoin d'un nonce généré dans le middleware et transmis aux composants. Commence en mode Report-Only. Le détail de chaque en-tête est dans les en-têtes de sécurité HTTP expliqués.

5. Secrets qui passent dans les Client Components

Pourquoi c'est important. Il est facile qu'une clé privée finisse dans un composant client par erreur, surtout quand l'IA réécrit des fichiers et déplace des imports. Si elle apparaît dans le JavaScript servi, elle est déjà compromise.

Comment vérifier. Après next build, cherche dans .next/static des chaînes comme sk_live, service_role, sk-ant ou des URL de webhooks. Si elles apparaissent, fais-les tourner et déplace-les côté serveur avec import 'server-only' comme garde-fou.

6. Images distantes et requêtes vers des URL de l'utilisateur

Pourquoi c'est important. next/image optimise les images via ton serveur. Si images.remotePatterns autorise n'importe quel hôte, n'importe qui peut utiliser ton serveur comme proxy d'images et consommer ton quota. Idem pour une route d'API qui télécharge l'URL que lui passe l'utilisateur : elle peut pointer vers des services internes de ton infrastructure (SSRF).

Comment corriger. Limite remotePatterns aux domaines que tu utilises vraiment. Si une route doit télécharger des URL externes, valide le protocole (https uniquement), rejette les IP privées et les noms internes, et mets un délai maximum.

7. Redirections ouvertes

Pourquoi c'est important. Le classique redirect(searchParams.next) après le login permet de construire des liens sur ton domaine qui finissent sur un site de phishing : tondomaine.com/login?next=https://malveillant.example.

Comment corriger. N'accepte que des chemins relatifs qui commencent par / (et pas par //), ou compare avec une liste de destinations autorisées.

8. Fichiers qui ne devraient pas être accessibles

Pourquoi c'est important. Tout ce qui est dans public/ est servi tel quel : un .env copié là par erreur, un dump de base de données ou un service-account.json sont à une URL de distance. Et les source maps en production permettent de lire ton code client avec les noms d'origine.

Comment vérifier. Essaie tondomaine.com/.env, /.git/HEAD et ouvre un fichier JS du bundle pour voir s'il se termine par une ligne sourceMappingURL pointant vers un .map accessible. Regarde le dossier public/ avec les yeux d'un inconnu.

9. Cookies de session et bibliothèques d'authentification

Pourquoi c'est important. Auth.js (NextAuth), Clerk ou Supabase avec son paquet serveur configurent correctement les cookies par défaut. Ce qui échoue, c'est ce que tu ajoutes : un cookie à toi sans HttpOnly, un AUTH_SECRET faible ou copié d'un tutoriel, ou la session stockée dans localStorage.

Comment corriger. Génère le secret avec openssl rand -base64 32, stocke-le sans préfixe public, et pour tout cookie à toi utilise Secure, HttpOnly et SameSite=Lax.

10. Dépendances et version de Next.js

Pourquoi c'est important. Ton app traîne des centaines de paquets, et Next.js lui-même publie des correctifs de sécurité plusieurs fois par an. Le cas du middleware en 2025 a touché ceux qui ne mettaient pas à jour.

Comment corriger. npm audit avant chaque déploiement, Dependabot ou Renovate sur le dépôt, et une règle simple : mettre Next.js à jour le mois même où sort un correctif de sécurité.

Déploiement sur Vercel : trois détails

  • Environnements. Les variables ont une portée (Production, Preview, Development). Ne donne pas aux déploiements de preview les identifiants de production : une preview est une URL publique avec ton code le plus récent.
  • Protection des previews. Active la Deployment Protection pour que les URL de preview exigent une connexion Vercel ; sinon, n'importe qui avec le lien voit la branche en cours.
  • En-têtes. Ceux de next.config.js s'appliquent sur Vercel tels quels ; si tu utilises aussi vercel.json, ne les duplique pas.

Ta checklist de 2 minutes

  • Aucune variable NEXT_PUBLIC_ ne contient de secret ; les modules avec des clés portent import 'server-only'.
  • Chaque Route Handler et Server Action vérifie la session et valide l'entrée ; l'id de l'utilisateur vient de la session.
  • Next.js dans une version corrigée ; le middleware n'est pas la seule couche d'auth.
  • En-têtes de sécurité dans next.config.js ; poweredByHeader: false ; CSP au moins en mode rapport.
  • Bundle sans sk_live, service_role ni webhooks ; source maps désactivées.
  • remotePatterns limités ; rien ne télécharge des URL de l'utilisateur sans validation.
  • Redirections seulement vers des chemins relatifs.
  • public/ sans fichiers sensibles ; .env et .git inaccessibles.
  • Cookies avec Secure, HttpOnly et SameSite ; AUTH_SECRET aléatoire.
  • npm audit propre ; previews protégées et sans secrets de production.

Vérifie tout ça en 30 secondes

Repasser cette liste à la main à chaque déploiement est fastidieux et s'oublie. Scanaris fait des vérifications en lecture seule sur ton site publié : en-têtes, secrets exposés dans le JavaScript, fichiers sensibles accessibles, source maps, cookies et CORS. Chaque résultat arrive avec un prompt prêt à coller dans Cursor ou v0 avec la correction exacte pour Next.js. Si tu le laisses en surveillance, il te prévient quand une session de vibe coding rouvre quelque chose. Pour approfondir ta stack, il y a la page sécurité pour Next.js et la checklist générale de lancement.

Questions fréquentes

Les Server Actions sont-elles sûres par défaut ?

Elles sont plus pratiques qu'une route d'API, pas plus sûres. Next.js les expose comme des endpoints publics ; l'authentification et la validation, c'est toi qui les mets dans chacune.

Le middleware protège-t-il mes routes ?

Il sert à rediriger et à faire des vérifications peu coûteuses, mais il ne doit pas être la seule barrière. Après le cas de 2025, la règle est de vérifier la session aussi là où les données sont servies.

Ai-je besoin d'une CSP avec Next.js ?

Oui, mais avec un nonce, et en commençant en mode rapport. Sans nonce, une CSP stricte bloque les scripts inline du framework lui-même et la page reste blanche.

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