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

Sécurité

Sécuriser un webhook Cloudflare Workers relié à WordPress à l’edge

Vérifier la légitimité d'un webhook avant même qu'il n'atteigne WordPress, directement à l'edge via Cloudflare Workers : la recette pour un site à fort trafic combinant les deux briques.

Par Clément Hadrot • 23 septembre 2025 • 5 min de lecture • Aucun commentaire
Sécuriser un webhook Cloudflare Workers relié à WordPress à l'edge

« Vérifie la signature avant même de réveiller PHP » : c’est le principe qui a guidé la recette présentée ici, construite pour un site e-commerce à fort trafic combinant Cloudflare devant une infrastructure WordPress classique. Le site recevait plusieurs centaines de webhooks par heure en provenance d’un prestataire de paiement et d’un service de gestion des stocks, et chaque requête, même invalide, déclenchait un chargement complet de WordPress avant d’être rejetée par le code applicatif.

Cloudflare Workers permet d’exécuter du code JavaScript directement à l’edge, avant que la requête n’atteigne le serveur d’origine. Pour un webhook, cela signifie qu’il devient possible de vérifier la signature cryptographique de la requête entrante, et de la rejeter immédiatement en cas d’échec, sans jamais solliciter l’origine WordPress. Cette recette détaille comment mettre en place ce filtrage, sans entrer dans les questions de performance globale de l’architecture.

Problème : chaque requête invalide sollicite inutilement l’origine

Avant la mise en place du filtrage edge, chaque webhook reçu, valide ou non, déclenchait un chargement complet de WordPress : initialisation du noyau, chargement des extensions actives, exécution du hook rest_api_init, avant que la fonction de rappel de la route ne vérifie enfin la signature et ne rejette la requête si elle était invalide. Sur un site recevant des tentatives répétées, légitimes ou malveillantes, ce coût de traitement inutile pesait directement sur la charge du serveur d’origine.

Le déplacement de la vérification à l’edge, avant même que la requête n’atteigne l’origine, permet de rejeter en quelques millisecondes ce qui n’a de toute façon aucune chance d’être traité, sans jamais mobiliser PHP ni la base de données WordPress.

Snippet : vérification HMAC dans un Worker Cloudflare

Le Worker intercepte la requête entrante sur le chemin du webhook, recalcule la signature HMAC attendue à partir du corps de la requête et d’un secret partagé, puis compare cette signature à celle fournie dans l’en-tête par le service tiers :

L'essentiel à retenir : Vérifier la signature HMAC avant l'origine WordPress ; Rejeter à l'edge plutôt que solliciter PHP inutilement ; Journaliser les rejets pour détecter les tentatives répétées
export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    if (url.pathname !== '/wp-json/paiement/v1/webhook') {
      return fetch(request);
    }

    const body = await request.clone().text();
    const signatureRecue = request.headers.get('X-Signature');
    const cle = await crypto.subtle.importKey(
      'raw',
      new TextEncoder().encode(env.WEBHOOK_SECRET),
      { name: 'HMAC', hash: 'SHA-256' },
      false,
      ['sign']
    );
    const signatureCalculee = await crypto.subtle.sign('HMAC', cle, new TextEncoder().encode(body));
    const hexCalculee = [...new Uint8Array(signatureCalculee)]
      .map(b => b.toString(16).padStart(2, '0')).join('');

    if (hexCalculee !== signatureRecue) {
      return new Response('Signature invalide', { status: 401 });
    }

    return fetch(request);
  }
};

Variante : limiter le débit par adresse IP avant même la vérification de signature

Pour un site particulièrement exposé, une seconde couche de filtrage s’ajoute utilement avant même le calcul de la signature : une limitation de débit par adresse IP source, exploitant l’API Cloudflare de limitation de requêtes disponible depuis un Worker. Cette limitation évite qu’une adresse malveillante ne consomme des ressources de calcul, même minimes, en soumettant un très grand nombre de signatures invalides en peu de temps.

  1. Définir un seuil raisonnable, par exemple soixante requêtes par minute par adresse IP sur ce chemin précis.
  2. Retourner un code 429 avec un en-tête Retry-After en cas de dépassement.
  3. Journaliser les dépassements dans Cloudflare Logpush pour une analyse ultérieure.

Variante : conserver une trace des rejets pour détecter les tentatives répétées

Rejeter silencieusement une requête invalide prive l’équipe de sécurité d’une information précieuse : la répétition de tentatives échouées depuis une même origine constitue souvent le signe avant-coureur d’une tentative de découverte du secret partagé par force brute, ou d’un dérèglement chez le partenaire émetteur légitime.

  • Envoyer un événement structuré vers Cloudflare Logpush à chaque rejet de signature.
  • Alerter automatiquement au-delà d’un seuil de rejets consécutifs depuis une même adresse.
  • Conserver, côté WordPress, un compteur des webhooks effectivement traités pour comparer avec le volume filtré à l’edge.

Un Worker placé devant l’origine n’est pas un gadget de performance : c’est un premier videur à l’entrée, qui évite à WordPress de traiter des requêtes dont le sort est déjà scellé avant même leur arrivée.

En résumé

Déplacer la vérification de signature d’un webhook vers l’edge, avec Cloudflare Workers, ne remplace pas la vigilance côté WordPress : l’origine doit continuer de vérifier elle-même la légitimité de ce qu’elle reçoit, au cas où le Worker serait contourné ou mal configuré. Mais ce filtrage précoce réduit considérablement le nombre de requêtes malformées qui atteignent réellement le serveur d’origine, tout en offrant un point d’observation supplémentaire pour repérer les tentatives suspectes avant qu’elles ne se transforment en incident.

Partager :

À propos de l'auteur

Clément Hadrot

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

Voir tous ses articles

Dans la même veine

À lire aussi