Sécurisation des Webhooks et gestion des accès API
Les webhooks et les clés d'API sont les portes d'entrée les plus exposées de notre plateforme : publication de messages, déclenchement de modération, écritures en base. Ce guide décrit les contrôles appliqués sur notre API Gateway — la même passerelle qui dessert Kurotsuki Studio et nos utilitaires de modération. Public visé : développeurs backend exposant des endpoints à des partenaires ou à des services tiers.
La règle fondamentale est de ne jamais faire confiance au réseau : chaque requête entrante doit être authentifiée, horodatée, limitée en débit et journalisée, même lorsqu'elle provient d'un partenaire connu.
Valider les payloads : signature, horodatage et schéma
Exigez une signature HMAC-SHA256 calculée sur le corps brut de la requête avec un secret partagé, transmise dans un en-tête dédié (par exemple X-Signature-256: sha256=…). Comparez les signatures en temps constant pour empêcher les attaques par canal temporel, et rejetez toute requête dont l'horodatage (X-Timestamp) s'écarte de plus de cinq minutes de l'horloge serveur afin de neutraliser les attaques par rejeu. Validez ensuite le JSON contre un schéma strict : types, longueurs maximales, énumérations fermées et refus des champs inconnus. Un payload qui échoue à la validation reçoit une erreur 400 générique, sans détail interne exploitable.
Mitigation des abus : quotas, allowlists et idempotence
Appliquez une limitation de débit par clé d'API et par adresse IP (par exemple 60 requêtes/minute avec file d'attente et en-têtes Retry-After), et durcissez les routes sensibles (envoi de messages, sanctions) avec des quotas séparés plus restrictifs. Lorsque l'émetteur dispose d'adresses IP stables, ajoutez une allowlist réseau en défense complémentaire — jamais en substitut de la signature. Rendez les opérations critiques idempotentes via une clé d'idempotence (Idempotency-Key) conservée 24 heures : toute répétition accidentelle ou malveillante retourne la réponse d'origine sans réexécuter l'effet de bord.
Secrets, en-têtes HTTP et rotation
Stockez les secrets de webhook et les clés d'API dans un gestionnaire de secrets ou, a minima, dans des variables d'environnement injectées au déploiement — jamais dans le dépôt ni dans les journaux. Attribuez à chaque intégration sa propre clé à périmètre restreint (lecture seule vs écriture, guildes autorisées) afin qu'une compromission reste circonscrite. Faites tourner les secrets au moins une fois par an et immédiatement après tout incident, en maintenant brièvement deux secrets actifs (primaire + précédent) pour une rotation sans interruption. Côté réponses, exposez des en-têtes de sécurité systématiques et des erreurs normalisées sans fuite d'implémentation :
// Middleware Express — vérification HMAC + fraîcheur + rate limit (extrait)
import crypto from "node:crypto";
const SECRET = process.env.WEBHOOK_SECRET;
const WINDOW_MS = 5 * 60 * 1000;
export function verifyWebhook(req, res, next) {
const sig = req.headers["x-signature-256"]; // "sha256=<hex>"
const ts = Number(req.headers["x-timestamp"]);
if (!sig || !Number.isFinite(ts)) return res.status(401).json({ error: "unauthorized" });
if (Math.abs(Date.now() - ts) > WINDOW_MS) return res.status(401).json({ error: "stale_request" });
const expected = "sha256=" + crypto.createHmac("sha256", SECRET).update(req.rawBody).digest("hex");
const a = Buffer.from(expected), b = Buffer.from(String(sig));
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
return res.status(401).json({ error: "unauthorized" });
}
next();
}
# En-têtes de réponse recommandés (Nginx ou middleware applicatif)
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
Réponse à incident et rotation des secrets
En cas de suspicion de compromission (pics d'appels anormaux, erreurs 401 massives suivies de succès, signalement d'un partenaire), révoquez immédiatement la clé concernée, générez-en une nouvelle à périmètre identique et diffusez-la par un canal sécurisé distinct du dépôt de code. Analysez ensuite les journaux sur une fenêtre de sept jours pour identifier les appels illégitimes et leurs effets, puis consignez l'incident : horodatage, clé concernée, requêtes incriminées, mesures correctives et date de rotation suivante. Cette discipline transforme chaque alerte en renforcement durable : règles de validation resserrées, quotas ajustés et périmètres de clés réduits au strict nécessaire.
À retenir
Authentifier (HMAC en temps constant), horodater (fenêtre anti-rejeu de 5 minutes), valider (schéma strict), limiter (quotas par clé et par IP), idempotenter (clés 24 h) et journaliser sans les secrets : ces six contrôles couvrent l'essentiel des attaques contre webhooks et API. Ils se déploient derrière le frontal décrit dans notre guide 3 sur l'infrastructure (Nginx, garde-fous, sondes), et protègent les services construits selon le guide 1 sur l'architecture des bots Discord.