How to verify a webhook signature

Written By Team BugSmash

Last updated 18 days ago

To ensure that incoming webhook requests are genuinely sent by BugSmash, you can verify the webhook signature using the secret key generated during webhook creation.

Important Notes

  • The secret key is automatically generated by the system.

  • The secret key is shown only once at the time of creation.

  • Make sure to copy and securely store the key, because it will not be visible again later.

  • Signature verification is completely optional, but highly recommended for security.


Headers Sent in Every Webhook Request

Every webhook request includes these headers:

  1. X-Webhook-Timestamp

  2. X-BugSmash-Signature

Request Headers Sample

{ "user-agent": "GuzzleHttp/7", "content-length": "971", "accept": "application/json", "content-type": "application/json", "x-bugsmash-signature": "a96abf9eaba9dda8bf2b71d171cbfd3faf5da8a974f1565e298ed88a39815bb9", "x-forwarded-for": "122.179.130.125", "x-forwarded-host": "wh178b7249a104b41ac3.free.beeceptor.com", "x-forwarded-proto": "https", "x-webhook-timestamp": "1777121034", "accept-encoding": "gzip" } 

How the Signature is Generated

The X-BugSmash-Signature is generated using:

HMAC_SHA256(secret_key, timestamp + '.' + payload) 

Where:

  • secret_key β†’ your webhook secret key

  • timestamp β†’ value from X-Webhook-Timestamp

  • payload β†’ the raw JSON request body exactly as received


Verification Flow

To verify the webhook:

  1. Read the incoming:

    • X-Webhook-Timestamp

    • X-BugSmash-Signature

    • Raw request body

  2. Generate a new signature on your server using the same logic.

  3. Compare:

    • Generated signature

    • Incoming X-BugSmash-Signature

If both match, the webhook request is valid.


Node.js Verification Example

const crypto = require("crypto"); function verifyWebhookSignature({ secretKey, // your copied secret-key payload, // raw JSON payload receivedTimestamp, // x-webhook-timestamp receivedSignature, // x-bugsmash-signature }) { // Step 1: Create signed payload const signedPayload = `${receivedTimestamp}.${JSON.stringify(payload)}`; // Step 2: Generate expected signature const expectedSignature = crypto .createHmac("sha256", secretKey) .update(signedPayload) .digest("hex"); // Step 3: Compare signatures securely return crypto.timingSafeEqual( Buffer.from(expectedSignature), Buffer.from(receivedSignature), ); }