SocialHook
Dokumentation/Sicherheit & Signierung

Sicherheit & Payload-Signierung

Jedes SocialHook-Payload wird mit HMAC-SHA256 unter Verwendung deines geheimen Schlüssels signiert. Du musst diese Signatur auf deinem Server vor der Verarbeitung jeder Nachricht verifizieren — dies schützt dich vor gefälschten Payloads.

So funktioniert die Signierung

Wenn SocialHook ein Payload an deine Webhook-URL liefert, berechnet es einen HMAC-SHA256-Hash des rohen Request-Body mit deinem geheimen Schlüssel. Dieser Hash wird im X-SocialHook-Signature HTTP-Header im Format sha256=<hex_digest> gesendet.

Auf deinem Server berechnest du denselben Hash mit demselben geheimen Schlüssel und dem rohen Body — und vergleichst die beiden Werte. Wenn sie übereinstimmen, ist das Payload authentisch.

Überspringe niemals die Signaturverifizierung. Ohne sie kann jeder, der deine Webhook-URL kennt, gefälschte Payloads an deinen Server senden.

Verifizierung — 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)
})

Verifizierung — 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

Verifizierung — 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);

Sicherheits-Best-Practices

Verwende immer timingSafeEqual — ein einfacher Zeichenfolgenvergleich ist anfällig für Timing-Angriffe. Verwende crypto.timingSafeEqual() (Node), hmac.compare_digest() (Python) oder hash_equals() (PHP).
Signiere den rohen Body, nicht gepartes JSON — berechne den HMAC über die rohen Request-Body-Bytes vor jeder JSON-Parsierung. Verschiedene JSON-Serialisierer können unterschiedliche Byte-Sequenzen erzeugen.
Speichere deinen geheimen Schlüssel als Umgebungsvariable — hartcodiere ihn nie im Quellcode oder committe ihn in ein Repository.
Gib 200 vor der Verarbeitung zurück — SocialHook wartet bis zu 10 Sekunden auf deine Antwort. Gib sofort 200 zurück und verarbeite das Payload asynchron.
Verwende nur HTTPS — SocialHook liefert nur an HTTPS-Endpunkte. Einfache HTTP-Endpunkte werden bei der Konfiguration abgelehnt.
Implementiere Idempotenz — In seltenen Fällen kann SocialHook dasselbe Ereignis zweimal liefern. Speichere delivery_id-Werte und überspringe Duplikate.
Rotiere deinen geheimen Schlüssel regelmäßig — Generiere einen neuen geheimen Schlüssel in deinen Dashboard-Einstellungen und aktualisiere deine Server-Umgebungsvariable.
Eine Sicherheitslücke gefunden? Bitte melde es verantwortungsvoll an security@socialhook.io. Veröffentliche es nicht öffentlich, bevor wir die Möglichkeit hatten, es zu beheben. Wir antworten innerhalb von 72 Stunden.