Technique~8 min · intermédiaire

Les failles de sécurité de base sur Next.js

La plupart des failles que je trouve en audit ne sont pas sophistiquées : ce sont des oublis. Voici les cinq trous les plus courants sur une app Next.js, et le correctif de chacun — avant que quelqu'un ne les trouve pour toi.

StackNext.jsserver-onlyauthIDORXSSCSRF
01

Les cinq trous classiques

Secrets exposés

Une clé mise dans une variable NEXT_PUBLIC_ finit dans le bundle client, lisible par tous.

Routes non protégées

Une API route sans vérification de session : n'importe qui appelle l'endpoint directement.

IDOR

On vérifie que l'user est connecté, mais pas que la ressource lui appartient. Il change l'id et lit les données d'un autre.

XSS

dangerouslySetInnerHTML sur du contenu utilisateur non nettoyé = injection de script.

02

Garder les secrets côté serveur

En Next.js, la frontière client/serveur est facile à franchir par accident. Le réflexe : marquer les modules sensibles server-only, et se souvenir que tout ce qui est NEXT_PUBLIC_ est public par définition.

lib/db.tsTSCopier
// lib/db.ts — empeche ce module de finir dans le bundle client
import "server-only";
// une variable SANS prefixe NEXT_PUBLIC_ n'est jamais exposee au navigateur
const dbUrl = process.env.DATABASE_URL; // OK, cote serveur uniquement
// NEXT_PUBLIC_API_KEY -> visible dans le bundle : ne JAMAIS y mettre un secret
À retenir

Où stocker et injecter les secrets proprement, c'est tout gérer ses secrets proprement.

03

Authentifier ET autoriser

L'erreur la plus fréquente et la plus grave : vérifier qui est l'utilisateur, mais pas ce à quoi il a droit. Chaque route qui lit ou modifie une ressource doit vérifier que la ressource appartient bien à l'utilisateur.

route.tsTSCopier
// app/api/invoices/[id]/route.ts
export async function GET(req, { params }) {
const session = await auth();
if (!session) return new Response("Unauthorized", { status: 401 });
const invoice = await db.invoice.findUnique({ where: { id: params.id } });
// IDOR : sans ce check, un user lit les factures d'un autre en changeant l'id
if (invoice.orgId !== session.orgId) {
return new Response("Forbidden", { status: 403 });
}
return Response.json(invoice);
}
Attention

Ne fais jamais confiance à un id venant du client. Vérifie systématiquement la propriété côté serveur — c'est la faille numéro un des SaaS.

04

Le reste du minimum

·valide toute entrée avec un schéma (Zod) avant de la toucher — jamais de confiance aveugle ;
·des cookies de session en httpOnly + Secure + SameSite pour bloquer le vol et le CSRF ;
·des en-têtes de sécurité (CSP, HSTS) via next.config ou le middleware ;
·du rate limiting sur les routes sensibles (login, paiement) pour bloquer le brute-force.
À retenir

Deux de ces points ont leur article : l'authentification dans une app Next.js et rate limiting et protection d'API.

05

Sources & ressources

Sources & ressources
01Next.js — How to think about data security in Next.jsLe guide officiel : Data Access Layer, server-only, taint, et la règle « ré-autoriser dans chaque Server Action ».02Next.js — Environment variables (NEXT_PUBLIC_)Explique noir sur blanc que toute variable NEXT_PUBLIC_ est inlinée dans le bundle JS au build.03Next.js — Content Security PolicyComment poser une CSP avec nonce via le middleware, ou en statique dans next.config.04OWASP Top 10 — A01: Broken Access ControlLa catégorie numéro un du Top 10 : elle couvre exactement l'IDOR décrit plus haut.05OWASP — IDOR Prevention Cheat SheetVérifier la propriété à chaque accès, à partir de la session — jamais d'un id fourni par le client.06OWASP — Cross Site Scripting Prevention Cheat SheetCite nommément dangerouslySetInnerHTML sans nettoyage comme vecteur XSS en React.07React — dangerouslySetInnerHTML (common components)La doc React elle-même : à n'utiliser que sur du HTML de confiance, déjà assaini.
En résumé

La sécurité de base n'est pas un sujet d'expert : c'est une checklist. Secrets côté serveur, chaque route qui autorise autant qu'elle authentifie, entrées validées, cookies durcis. Fais-en une passe systématique avant chaque mise en prod, et tu élimines 90% des failles réelles.

OWASP Top 10 ↗
À lire ensuite