Le WordPress d'aujourd'hui, décodé pour les développeurs

Headless & API

Un audit de sécurité headless a révélé une route Next.js oubliée

Une route de test laissée en production, accessible sans aucune vérification du jeton WordPress attendu : le récit d'une découverte d'audit et de sa correction.

Par WordPress Développement • 12 février 2024 • 5 min de lecture • Aucun commentaire
Un audit de sécurité headless a révélé une route Next.js oubliée

« Route non protégée, retour HTTP 200 sur un identifiant arbitraire. » C’est la ligne, sortie brute d’un scanner d’audit automatisé, qui a mis la puce à l’oreille d’une équipe technique en charge d’un site vitrine à forte audience, construit en Next.js et alimenté par un WordPress headless. La route en question, /api/debug/preview, n’apparaissait dans aucune documentation, n’était appelée par aucun composant du front, et pourtant répondait, sans exiger la moindre authentification.

L’enquête qui a suivi a permis de reconstituer l’origine du problème et surtout d’en tirer une méthode de correction reproductible. Cet article se concentre sur le diagnostic et la correction de cette faille d’accès ; il ne traite pas la question de la performance de cette route, qui n’était de toute façon jamais censée exister en production.

Comment la route a été créée

Quatorze mois plus tôt, un développeur avait ajouté cette route pour déboguer localement un problème de prévisualisation de brouillon WordPress. Elle interrogeait directement l’API REST de WordPress avec les identifiants d’un compte administrateur stockés en clair dans une variable d’environnement de développement, et renvoyait le contenu brut du post demandé, publié ou non. Le correctif temporaire n’avait jamais été retiré après résolution du bug initial : il avait simplement été oublié, noyé parmi des dizaines d’autres routes API du dossier pages/api.

Ce que l’audit a mis en lumière

L’audit de sécurité, mené sur l’ensemble du front headless, a listé systématiquement toutes les routes exposées sous /api, puis a testé chacune sans authentification. Sur la quarantaine de routes recensées, une seule répondait sans exiger le jeton WordPress attendu par les autres. Le scanner a immédiatement remonté un post en statut brouillon, contenant des informations qui n’auraient jamais dû fuiter avant leur publication officielle.

L'essentiel à retenir : Route de développement jamais supprimée avant mise en production ; Absence totale de vérification du jeton attendu ; Cartographie systématique des routes exigée après l'incident

Le correctif appliqué

La correction s’est faite en deux temps. D’abord, suppression pure et simple de la route de débogage, devenue inutile depuis que l’équipe utilisait le mécanisme de prévisualisation officiel de WordPress avec un jeton signé et une expiration courte. Ensuite, ajout d’un middleware Next.js appliqué à l’ensemble du dossier /api, vérifiant systématiquement la présence et la validité d’un en-tête d’autorisation avant de laisser passer la moindre requête vers une route sensible :

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  if (request.nextUrl.pathname.startsWith('/api/wp')) {
    const token = request.headers.get('x-wp-token');
    if (!token || token !== process.env.WP_FRONT_TOKEN) {
      return NextResponse.json({ error: 'unauthorized' }, { status: 401 });
    }
  }
  return NextResponse.next();
}

export const config = {
  matcher: '/api/wp/:path*',
};

Pourquoi ce type d’oubli est fréquent en headless

Un projet headless multiplie les surfaces d’exposition : le back-office WordPress classique, l’API REST ou WPGraphQL, et désormais toutes les routes du front lui-même, qui peuvent chacune parler directement à la base de contenu. Contrairement à un thème WordPress classique où tout transite par le cœur du CMS et ses propres vérifications, un front headless doit réimplémenter ses propres contrôles d’accès, route par route, ce qui multiplie les occasions d’en oublier un.

  • Aucune revue de code systématique sur les routes de débogage avant mise en production.
  • Pas d’inventaire centralisé des routes exposées par le front.
  • Absence de scan automatisé régulier des endpoints non documentés.

Ce que l’équipe a mis en place ensuite

Trois mesures ont suivi l’incident. D’abord, une revue trimestrielle de toutes les routes API du front, avec suppression systématique de tout ce qui n’est plus appelé par le code de production. Ensuite, un test automatisé, intégré à la chaîne d’intégration continue, qui liste dynamiquement les fichiers de routes et vérifie que chacune impose une authentification si elle touche à du contenu non public. Enfin, l’interdiction, formalisée dans les conventions de l’équipe, de committer une route de débogage sans la faire précéder d’un commentaire // TODO: remove before merge traqué par un linter personnalisé.

Une route de débogage qui fonctionne trop bien a tendance à survivre bien plus longtemps qu’elle ne le devrait, précisément parce que personne ne pense à la retester une fois le problème initial résolu.

En résumé

Cette découverte d’audit illustre un piège classique du headless : chaque route front devient un point d’entrée potentiel vers le contenu WordPress, et aucune n’hérite automatiquement des protections du cœur du CMS. Cartographier l’ensemble des routes exposées, et vérifier systématiquement qu’aucune ne contourne le mécanisme d’authentification prévu, devrait faire partie de tout audit de sécurité headless, au même titre que la vérification des en-têtes CORS ou des clés d’API exposées côté client.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi