Increase webhook security by validating the signature

Increase webhook security by validating the signature

When creating a JSON webhook turn on the option to “Add encoded signature in header” to include the webhook payload using HMAC-SHA-256 signature verification. The signature is sent in the header X-Mopinion-Signature and is encoded using a secret token you can enter when creating the webhook.

Validating the signature in your endpoint

  1. Extract the signature from the webhook header

  2. Get the raw webhook payload (before parsing)

  3. Generate a signature using your secret key

  4. Compare the generated signature with the received signature

Code Examples

Python
import base64 import hashlib import hmac import json def validate_webhook(payload: str, signature: str, secret_key: str) -> bool: """ Validate a webhook payload using HMAC-SHA-256. Args: payload (str): The raw webhook payload as a string signature (str): The signature from the webhook header secret_key (str): Your webhook secret key Returns: bool: True if the webhook is valid, False otherwise """ byte_key = secret_key.encode('utf-8') byte_payload = payload.encode('utf-8') expected_signature = base64.b64encode( hmac.new(byte_key, byte_payload, hashlib.sha256).digest() ).decode() return hmac.compare_digest(signature, expected_signature) # Example usage def webhook_handler(request): signature = request.headers.get('X-Mopinion-Signature') payload = request.body # Raw request body as string secret_key = 'your_secret_key' if validate_webhook(payload, signature, secret_key): # Process valid webhook data = json.loads(payload) # ... handle the webhook data else: # Reject invalid webhook raise ValueError("Invalid webhook signature")
Node.js
const crypto = require('crypto'); function validateWebhook(payload, signature, secretKey) { const expectedSignature = crypto .createHmac('sha256', secretKey) .update(payload) .digest('base64'); // Use timing-safe comparison return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expectedSignature) ); } // Example usage with Express app.post('/webhook', (req, res) => { const signature = req.headers['x-mopinion-signature']; const payload = JSON.stringify(req.body); const secretKey = 'your_secret_key'; if (validateWebhook(payload, signature, secretKey)) { // Process valid webhook // ... handle the webhook data res.sendStatus(200); } else { res.sendStatus(401); } });

Important Notes

  1. Always use timing-safe comparison methods to prevent timing attacks

  2. Process the raw payload before parsing it as JSON

  3. Keep your secret key secure and never expose it in client-side code

  4. The signature is base64 encoded

  5. The HMAC-SHA-256 algorithm is used for signature generation

Looking for labels? They can now be found in the details panel on the floating action bar.

Related content