Security

Signature Verification

Every webhook delivery includes a signature in the X-Webhook-Signature header. Verify this to ensure the request came from TokenBot.

How It Works

  1. TokenBot computes an HMAC-SHA256 of the raw request body using your webhook secret

  2. The signature is sent as X-Webhook-Signature: sha256=<hex_digest>

  3. You compute the same HMAC and compare

Node.js Example

const crypto = require('crypto');

function verifyWebhookSignature(body, signature, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(body, 'utf8')
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// Express middleware
app.post('/webhooks', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  
  if (!verifyWebhookSignature(req.body, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  const event = JSON.parse(req.body);
  // Process event...
  
  res.status(200).send('OK');
});

Python Example

Best Practices

  • Always verify signatures before processing events

  • Use crypto.timingSafeEqual (Node.js) or hmac.compare_digest (Python) to prevent timing attacks

  • Rotate your webhook secret periodically via POST /webhooks/:id/rotate-secret

  • Respond with 2xx quickly; process events asynchronously

Last updated

Was this helpful?