Skip to main content

Webhook Security

Overview

This documentation covers the security measures implemented for securing webhooks through signature generation and verification. The security of our webhooks is ensured using HMAC (Hash-Based Message Authentication Code) with SHA-256 hashing algorithm. This method confirms that the received webhook payloads are unaltered and from a trusted source.

Generating Webhook Signatures

When sending a webhook, we generate a signature using the payload and a secret key. The signature is then passed along with the webhook payload in the headers of the request.

Code Example for Signature Generation

The following is a Node.js code snippet for generating a HMAC SHA256 signature for the webhook payload:

import * as CryptoJS from 'crypto-js';

function generateSignature(body, secret) {
const hmac = CryptoJS.HmacSHA256(JSON.stringify(body), secret);
const hashInBase64 = CryptoJS.enc.Base64.stringify(hmac);
return hashInBase64;
}

// Usage
const body = { /* webhook body here */ };
const secret = /* Webhook secret */; // Ensure you have your secret key securely stored and retrieved
const signature = generateSignature(body, secret);

Sending the Signature

The generated signature should be included in the headers of the webhook request. The header key used is x-paf-webhook-hmac.

Verifying Webhook Signatures

To ensure the integrity and authenticity of the received webhook payloads, the receiver should verify the signature included in the request headers.

Code Example for Signature Verification

Below is a JavaScript (Node.js) snippet demonstrating how to verify the webhook signature on the receiver's end:

const CryptoJS = require('crypto-js');

function verifySignature(receivedSignature, receivedPayload, secret) {
const expectedSignature = CryptoJS.HmacSHA256(JSON.stringify(receivedPayload), secret);
const expectedSignatureInBase64 = CryptoJS.enc.Base64.stringify(expectedSignature);

return receivedSignature === expectedSignatureInBase64;
}

// Usage
const receivedSignature = req.headers['x-paf-webhook-hmac'];
const receivedPayload = req.body; // The payload received in the webhook
const secret = /* Your secret key, same as the sender's */;
const isVerified = verifySignature(receivedSignature, receivedPayload, secret);

if (isVerified) {
console.log('Webhook signature verified successfully!');
} else {
console.log('Failed to verify webhook signature.');
}

Best Practices

  1. Secure Your Secret Key: Ensure that your secret key is stored securely and is not hard-coded in your application code.
  2. Validate Payloads Promptly: Perform signature validation as soon as you receive the webhook payload to prevent replay attacks.
  3. Use HTTPS: Always use HTTPS for receiving webhook payloads to ensure the data is encrypted during transit.

By following these steps and utilizing the provided code snippets, you can secure your webhook integrations effectively against common vulnerabilities and ensure the data integrity and authenticity of the payloads you receive.