Spectra
Parcourir la doc

webhooks

Protection anti-replay

Comment Spectra empêche un webhook capturé d'être rejoué contre votre compte.


La protection anti-replay sur un webhook signé arrête deux attaques :

  1. Un attaquant qui a capturé une requête valide ne peut pas la renvoyer pour tirer le même ordre.
  2. Un émetteur mal comporté ne peut pas renvoyer accidentellement des messages obsolètes après des hoquets réseau.

Le mécanisme

Chaque requête porte X-Spectra-Timestamp. Le worker applique :

  • Fenêtre de fraîcheur — 5 minutes par défaut. Les requêtes avec des timestamps plus vieux que maintenant − 5 min sont rejetées avec 401.
  • Cache de nonce — le worker cache (secret_id, timestamp, body_hash) pendant la fenêtre de fraîcheur. Une seconde requête avec les trois identiques est rejetée avec 409 Conflict. Le cache est en mémoire uniquement (pas d'écriture Postgres par requête) donc peu coûteux.

Ensemble : une requête capturée est rejouable au plus 5 minutes, et seulement si l'attaquant gagne une course contre votre livraison originale.

Régler la fenêtre

Profil → Webhooks → secret → Advanced → Freshness window.

1 min   →  strict ; recommandé pour réseaux à faible latence
5 min   →  défaut
15 min  →  large ; uniquement si votre émetteur a un lag imprévisible

Descendre sous 1 minute est risqué — le décalage d'horloge entre émetteur et worker peut faire échouer des requêtes légitimes aux contrôles de fraîcheur.

Et l'idempotency ?

Idempotency (client_id) et anti-replay résolvent des problèmes différents. Idempotency permet au même émetteur de retenter en sécurité. Anti-replay empêche un émetteur différent de réutiliser une requête capturée. Utilisez les deux.

Symptômes de décalage d'horloge

Si vous voyez des requêtes légitimes rejetées avec timestamp out of range, l'horloge de votre émetteur dérive. Vérifiez NTP. L'erreur inclut le now-time du worker pour que vous calculiez le delta.