Aller au contenu principal
Développement Web · 7 min de lecture

Server Actions Next.js : 7 règles de sécurité en 2026

Server Actions sécurité en 2026 : découvrez 7 règles essentielles. Authentification, autorisation, validation Zod et limitation de l'exposition expliquées.

Par L'équipe ConsilioWEB
Server Actions Next.js : 7 règles de sécurité en 2026
Sommaire

La Server Actions sécurité repose sur une règle simple : traitez chaque action serveur comme un endpoint API public, donc authentifiez, autorisez et validez systématiquement chaque appel.

Les Server Actions de Next.js simplifient le développement. Vous écrivez une fonction serveur, vous l'appelez depuis un composant, et la donnée transite. Cette élégance cache pourtant un piège dangereux. Beaucoup d'équipes oublient qu'une Server Action devient une route HTTP exposée publiquement. Par conséquent, un attaquant peut l'invoquer sans passer par votre interface. Chez ConsilioWEB, notre équipe à Ussel audite régulièrement des projets Next.js et corrige ces failles. Demandez un audit de sécurité si votre application manipule des données sensibles.

Le modèle de menace des Server Actions

Une Server Action n'est pas une fonction privée. À la compilation, Next.js génère un identifiant unique et expose un endpoint POST associé. N'importe qui peut appeler cet endpoint avec une simple requête curl. C'est le point de départ de toute réflexion sur la Server Actions sécurité.

Le danger vient d'une illusion fréquente. Le code vit dans le même fichier que le composant, donc on le croit protégé. En réalité, la frontière client-serveur reste poreuse. Ainsi, un formulaire masqué dans l'interface ne masque jamais l'action sous-jacente.

Considérez ce scénario terrain. Une action deleteProject(id) n'est affichée qu'aux administrateurs dans l'UI. Cependant, l'endpoint reste joignable par tout utilisateur connecté, voire anonyme. Sans contrôle serveur, la suppression devient triviale pour un attaquant motivé.

Pourquoi le CSRF mérite votre attention ?

Next.js intègre une protection contre les requêtes intersites depuis la version 14. Le framework vérifie notamment l'en-tête Origin face à l'Host. Cette défense reste néanmoins partielle. Elle ne remplace ni l'authentification ni l'autorisation, qui demeurent votre responsabilité.

De plus, cette protection suppose une configuration correcte de vos domaines autorisés. Une erreur dans serverActions.allowedOrigins peut ouvrir une brèche. Pour renforcer cette couche, complétez avec des en-têtes adaptés, comme nous l'expliquons dans notre guide sur les headers de sécurité HTTP : CSP, HSTS et X-Frame-Options.

Authentifier et autoriser chaque action

La première règle de Server Actions sécurité tient en une phrase : aucune confiance implicite. Chaque action doit vérifier l'identité de l'appelant avant toute opération. Ne déléguez jamais ce contrôle au composant client, car le client ment toujours.

D'abord, récupérez la session côté serveur, dès la première ligne de l'action. Ensuite, rejetez immédiatement tout appel non authentifié. Cette discipline évite les exécutions fantômes déclenchées hors de votre interface.

1'use server'
2
3import { auth } from '@/lib/auth'
4
5export async function updateInvoice(formData: FormData) {
6 const session = await auth()
7 if (!session?.user) {
8 throw new Error('Non authentifié')
9 }
10 // suite de l'action...
11}

L'authentification ne suffit pourtant pas. Un utilisateur connecté n'a pas tous les droits. Par conséquent, vérifiez aussi l'autorisation, c'est-à-dire le droit précis d'agir sur cette ressource. Un client ne doit jamais modifier la facture d'un autre client.

Authentification ou autorisation : quelle différence ?

L'authentification répond à la question « qui êtes-vous ? ». L'autorisation répond à « avez-vous le droit de faire ceci ? ». Confondre les deux constitue l'erreur la plus répandue que nous croisons sur le terrain.

Voici un contrôle d'autorisation concret. Vérifiez que la ressource appartient bien à l'utilisateur courant.

1const invoice = await db.invoice.findUnique({ where: { id } })
2if (invoice?.ownerId !== session.user.id) {
3 throw new Error('Accès refusé')
4}

Cette logique relève du modèle server-first que nous avons détaillé dans notre retour d'expérience sur les React Server Components en production. Centraliser ces vérifications réduit nettement la surface d'attaque.

Pourquoi valider les entrées avec Zod ?

Toute donnée venant du client est hostile par défaut. Le FormData reçu peut contenir n'importe quoi, y compris des champs injectés manuellement. Ainsi, la validation des entrées forme un pilier de la Server Actions sécurité.

Zod s'impose comme l'outil de référence en 2026. Cette bibliothèque définit un schéma typé, puis rejette toute entrée non conforme. De plus, elle infère automatiquement les types TypeScript, ce qui évite la double déclaration.

1import { z } from 'zod'
2
3const schema = z.object({
4 amount: z.number().positive().max(100000),
5 email: z.string().email(),
6})
7
8const result = schema.safeParse({
9 amount: Number(formData.get('amount')),
10 email: formData.get('email'),
11})
12
13if (!result.success) {
14 return { error: 'Données invalides' }
15}

Ne validez jamais uniquement côté client. La validation HTML5 ou React améliore l'expérience, mais ne protège rien. En effet, un attaquant contourne le navigateur sans difficulté. La validation serveur reste donc la seule barrière fiable.

Pensez également aux limites métier. Un montant négatif, un quota dépassé ou un identifiant inexistant doivent provoquer un rejet explicite. Par exemple, plafonnez les montants et bornez les longueurs de chaîne pour éviter les abus.

Limiter l'exposition et les données renvoyées

Une Server Action ne doit jamais renvoyer plus que nécessaire. Retourner un objet utilisateur complet expose souvent des champs sensibles. Notamment, on retrouve fréquemment des hash de mots de passe ou des tokens dans ces fuites.

Sélectionnez donc explicitement les champs renvoyés au client. Ne faites jamais confiance à un select implicite de votre ORM. Cette rigueur limite la surface d'exposition et respecte le principe de moindre privilège.

Pratique

Risque

Recommandation 2026

Renvoyer l'objet DB complet

Fuite de champs sensibles

Sélectionner uniquement les champs utiles

Valider côté client seulement

Contournement trivial

Valider systématiquement avec Zod côté serveur

Action sans contrôle d'identité

Endpoint public exploitable

Authentifier et autoriser chaque appel

Erreurs détaillées renvoyées

Divulgation d'infos internes

Messages génériques côté client, logs côté serveur

Mutations sans rate limiting

Abus et déni de service

Limiter le débit par utilisateur et par IP

Soignez aussi vos messages d'erreur. Une erreur trop détaillée renseigne l'attaquant sur votre architecture. Par conséquent, renvoyez un message générique au client, tout en conservant le détail dans vos logs serveur.

Faut-il limiter le débit des actions ?

Oui, le rate limiting protège vos actions sensibles contre les abus. Une action de connexion ou d'envoi d'e-mail mérite une limite stricte. Sans ce garde-fou, un script peut multiplier les appels et saturer vos ressources.

Plusieurs approches existent en 2026. Vous pouvez utiliser un store Redis avec une fenêtre glissante, ou un service edge dédié. L'essentiel reste d'appliquer la limite côté serveur, au plus près de l'action.

Audit, logs et bonnes pratiques

La sécurité ne s'arrête pas au code. Elle se prouve par l'observabilité. Journalisez chaque mutation sensible avec l'identité de l'appelant, l'horodatage et la ressource visée. Ainsi, vous reconstituez tout incident après coup.

Adoptez une checklist systématique avant chaque mise en production. Voici les sept règles que notre équipe applique sur chaque projet Next.js.

  1. Authentifier chaque Server Action dès sa première ligne.
  2. Autoriser l'accès à la ressource précise, pas seulement la session.
  3. Valider toutes les entrées avec un schéma Zod côté serveur.
  4. Limiter les données renvoyées aux seuls champs nécessaires.
  5. Rate-limiter les actions sensibles par utilisateur et par IP.
  6. Masquer les erreurs internes derrière des messages génériques.
  7. Journaliser chaque mutation pour l'audit et la traçabilité.

Cette discipline s'inscrit dans une démarche de qualité plus large. Pour aller plus loin sur les nouveautés et correctifs du framework, consultez notre analyse de Next.js 16 : Turbopack, React Compiler et failles critiques corrigées. La compréhension de l'App Router aide aussi, comme dans notre guide de migration Next.js 15.

Enfin, automatisez vos contrôles. Un linter, des tests d'intégration et une revue de code régulière repèrent les régressions tôt. En 2026, l'analyse statique détecte déjà de nombreux schémas dangereux, mais elle ne remplace pas le jugement humain.

La Server Actions sécurité n'est donc pas une option, mais une posture par défaut. Chaque action doit prouver son innocuité avant de toucher vos données. Notre équipe à Ussel accompagne les PME et les CTO francophones dans cette mise en conformité. Demandez un devis pour un audit complet de votre application Next.js.

Questions fréquentes sur la Server Actions sécurité

Les Server Actions sont-elles exposées publiquement ?

Oui, chaque Server Action génère un endpoint HTTP joignable publiquement. Next.js lui attribue un identifiant unique à la compilation, puis l'expose via une route POST. Un attaquant peut l'appeler directement avec curl, sans passer par votre interface. Vous devez donc authentifier et autoriser chaque appel côté serveur.

Next.js protège-t-il déjà contre le CSRF ?

Partiellement. Depuis la version 14, Next.js vérifie l'en-tête Origin face à l'Host pour bloquer les requêtes intersites. Cette protection ne remplace toutefois ni l'authentification ni l'autorisation. Configurez correctement allowedOrigins et complétez avec des en-têtes de sécurité dédiés pour une défense robuste.

Faut-il valider les entrées même avec TypeScript ?

Oui, absolument. TypeScript vérifie les types à la compilation, jamais à l'exécution. Les données reçues d'un client passent au-delà de ces garanties. Utilisez donc Zod pour valider chaque entrée au moment de l'exécution. Cette validation serveur reste la seule barrière fiable contre les données malveillantes.

Comment limiter les données renvoyées par une action ?

Sélectionnez explicitement les champs dans votre requête ORM. N'employez jamais de select implicite renvoyant l'objet complet. Définissez une projection précise, par exemple { id: true, name: true }. Cette rigueur évite de divulguer des hash, des tokens ou des champs internes sensibles au client.

Pour aller plus loin

Partager
Un projet en tête ?Discutons de votre projet web et transformons vos idées en réalité.
Devis gratuit →