SocialHook
Documentation/Sécurité & signature

Sécurité & Signature des payloads

Chaque payload SocialHook est signé avec HMAC-SHA256 en utilisant votre clé secrète. Vous devez vérifier cette signature sur votre serveur avant de traiter tout message — cela vous protège contre les payloads falsifiés.

Comment la signature fonctionne

Quand SocialHook livre un payload à votre URL webhook, il calcule un hash HMAC-SHA256 du corps de la requête brute en utilisant votre clé secrète. Ce hash est envoyé dans l'en-tête HTTP X-SocialHook-Signature au format sha256=<hex_digest>.

Sur votre serveur, vous calculez le même hash en utilisant la même clé secrète et le corps brut — et vous comparez les deux valeurs. Si elles correspondent, le payload est authentique.

Ne sautez jamais la vérification de signature. Sans cela, quiconque connaît votre URL webhook peut envoyer de faux payloads à votre serveur.

Vérification — Node.js

Node.js / Express
const crypto = require('crypto')

function verifySocialHookSignature(req, secret) {
  const header = req.headers['x-socialhook-signature']
  if (!header) return false

  const hash = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(req.rawBody) // must be raw Buffer
    .digest('hex')

  // Use timingSafeEqual to prevent timing attacks
  return crypto.timingSafeEqual(
    Buffer.from(hash),
    Buffer.from(header)
  )
}

// In your Express middleware:
app.use(express.json({
  verify: (req, _, buf) => { req.rawBody = buf }
}))

app.post('/webhook', (req, res) => {
  if (!verifySocialHookSignature(req, process.env.SOCIALHOOK_SECRET)) {
    return res.status(401).send('Invalid signature')
  }
  // Safe to process
  res.sendStatus(200)
})

Vérification — Python

Python / Flask
import hmac
import hashlib
from flask import Flask, request, abort
import os

app = Flask(__name__)

def verify_signature(payload_body, signature_header, secret):
  if not signature_header:
    return False
  expected = 'sha256=' + hmac.new(
    secret.encode(),
    payload_body,
    hashlib.sha256
  ).hexdigest()
  return hmac.compare_digest(expected, signature_header)

@app.route('/webhook', methods=['POST'])
def webhook():
  sig = request.headers.get('X-SocialHook-Signature')
  if not verify_signature(request.data, sig, os.environ['SOCIALHOOK_SECRET']):
    abort(401)
  # Safe to process request.json
  return '', 200

Vérification — PHP

PHP
<?php
function verifySocialHookSignature($rawBody, $signatureHeader, $secret): bool {
  if (empty($signatureHeader)) return false;
  $expected = 'sha256=' . hash_hmac('sha256', $rawBody, $secret);
  return hash_equals($expected, $signatureHeader);
}

$rawBody = file_get_contents('php://input');
$sig = $_SERVER['HTTP_X_SOCIALHOOK_SIGNATURE'] ?? '';

if (!verifySocialHookSignature($rawBody, $sig, getenv('SOCIALHOOK_SECRET'))) {
  http_response_code(401);
  exit('Invalid signature');
}
$payload = json_decode($rawBody, true);
// Safe to process $payload
http_response_code(200);

Bonnes pratiques de sécurité

Utilisez toujours timingSafeEqual — une simple comparaison de chaînes est vulnérable aux attaques de timing. Utilisez crypto.timingSafeEqual() (Node), hmac.compare_digest() (Python), ou hash_equals() (PHP).
Signez le corps brut, pas le JSON analysé — calculez le HMAC sur les octets du corps de la requête brute avant tout traitement JSON. Différents sérialiseurs JSON peuvent produire différentes séquences d'octets.
Stockez votre clé secrète en tant que variable d'environnement — ne la codez jamais en dur dans le code source ou ne la commitez pas dans un dépôt.
Retournez 200 avant de traiter — SocialHook attend jusqu'à 10 secondes votre réponse. Retournez 200 immédiatement et traitez le payload de manière asynchrone.
Utilisez HTTPS uniquement — SocialHook ne livre qu'aux points de terminaison HTTPS. Les points de terminaison HTTP sont rejetés à la configuration.
Implémentez l'idempotence — Dans de rares cas SocialHook peut livrer le même événement deux fois. Stockez les valeurs delivery_id et ignorez les doublons.
Faites tourner votre clé secrète périodiquement — Générez une nouvelle clé secrète depuis les paramètres de votre tableau de bord et mettez à jour votre variable d'environnement serveur.
Vous avez trouvé une vulnérabilité de sécurité ? Veuillez la signaler de manière responsable à security@socialhook.io. Ne divulguez pas publiquement avant que nous ayons eu la chance de la traiter. Nous répondons dans les 72 heures.