Guide de sécurité pour développeurs

Checklist de sécurité Next.js pour la production

Traitez chaque Server Action et Route Handler comme un endpoint public, autorisez près des données, gardez les secrets côté serveur, posez les cookies de session côté serveur et déployez une CSP adaptée à votre rendu.

Réponse courte : Traitez chaque Server Action et Route Handler comme un endpoint public, autorisez près des données, gardez les secrets côté serveur, posez les cookies de session côté serveur et déployez une CSP adaptée à votre rendu.

1. Marquer les frontières serveur et client

Le code importé par un Client Component peut entrer dans le bundle navigateur. Gardez clients de base, clés de signature et appels privilégiés dans des modules server-only. Les variables d'environnement exposées au navigateur ne doivent contenir que des valeurs publiques. Inspectez le bundle de production.

Les Server Components réduisent le JavaScript client mais ne créent pas une autorisation. Une requête directe peut toujours atteindre Route Handlers et Server Actions.

2. Autoriser Server Actions et Route Handlers

Traitez une Server Action exportée comme une mutation appelable de l'extérieur. Validez les champs, chargez la session, vérifiez la permission et limitez la requête au tenant. Répéter le contrôle près des données protège aussi les appels hors UI.

'use server'
import 'server-only'
export async function renameProject(projectId, rawName) {
  const session = await verifySession();
  const name = validateProjectName(rawName);
  const project = await db.project.findFirst({
    where: { id: projectId, workspaceId: session.workspaceId }
  });
  if (!project || !session.can("project:update")) throw new Error("Not found");
  await db.project.update({ where: { id: project.id }, data: { name } });
}

3. Durcir sessions, cache et redirections

Posez les cookies d'authentification côté serveur avec HttpOnly, Secure, SameSite, un chemin limité et une expiration. Renouvelez-les à la connexion et aux changements de privilège. Validez la destination après connexion avec une liste interne.

Ne mettez pas en cache public une réponse personnalisée. Vérifiez rendu statique, revalidation et clés CDN dès que le résultat dépend des cookies, headers, rôles ou tenants.

Une politique à nonce exige un nonce frais par réponse et donc un rendu dynamique. Une politique par hash peut convenir aux assets statiques mais doit être régénérée au build. Commencez en report-only, testez navigation et intégrations, puis appliquez. Évitez les wildcards et conservez object-src 'none', base-uri 'self' et un frame-ancestors restrictif.

5. Revoir les bords à risque

Limitez la taille avant de parser les uploads, vérifiez leur traitement réel et stockez-les hors des chemins exécutables. Pour proxies d'images, aperçus d'URL et webhooks, validez destinations et signatures. Middleware ou Proxy peut faire un contrôle optimiste, mais l'autorisation sûre reste près des données.

Erreurs fréquentes

  • Supposer que 'use server' implique un appelant de confiance.
  • Vérifier la session dans un layout mais pas la mutation.
  • Retourner un objet ORM contenant des champs internes au client.
  • Placer un secret dans une variable exposée au navigateur.
  • Cacher une réponse tenant sans inclure ce tenant dans la frontière de cache.
  • Ajouter une CSP à nonce tout en attendant un rendu entièrement statique.

Checklist

  • Les modules server-only gardent secrets et clients privilégiés.
  • Chaque Server Action et Route Handler valide et autorise.
  • Les requêtes incluent la contrainte de tenant ou propriétaire.
  • Les cookies de session sont sûrs et renouvelés.
  • Les redirections internes sont validées.
  • Le contenu personnalisé n'est jamais caché publiquement.
  • La CSP est testée avec la stratégie de rendu choisie.
  • Uploads, webhooks et fetch sortants ont des contrôles dédiés.

Limites

La sécurité Next.js évolue selon versions et adaptateurs de déploiement. Vérifiez le comportement avec la documentation de la version et de l'hébergeur réellement livrés. Le framework ne corrige pas un modèle tenant inexact ou une règle produit manquante.

Sources primaires

Faire relire un dépôt Next.js

Appliquer ces contrôles au code et aux frontières produit réelles.

Discuter d'une revue de code