JAVASCRIPT

Verify Webhook Signatures for Security

Enhance webhook security by implementing signature verification in Node.js. Validate incoming requests to ensure they originate from trusted sources, preventing spoofing and tampering.

const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('crypto');

const app = express();

// Your secret key for verifying webhooks
const WEBHOOK_SECRET = 'your_super_secret_webhook_key'; // CHANGE THIS IN PRODUCTION!

// A raw body parser is needed to calculate the signature correctly
app.use(bodyParser.json({ verify: (req, res, buf) => {
  req.rawBody = buf.toString();
}}));

app.post('/webhook', (req, res) => {
  const signature = req.headers['x-webhook-signature']; // Or your specific header name

  if (!signature) {
    return res.status(401).send('No signature header provided.');
  }

  // Recompute the signature using the raw body and your secret
  // Example: HMAC SHA256
  const hmac = crypto.createHmac('sha256', WEBHOOK_SECRET);
  hmac.update(req.rawBody);
  const expectedSignature = `sha256=${hmac.digest('hex')}`; // Adjust prefix if needed

  // Compare the expected signature with the one from the header
  // Use crypto.timingSafeEqual to prevent timing attacks
  const isSignatureValid = crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );

  if (!isSignatureValid) {
    return res.status(403).send('Invalid signature.');
  }

  // Signature is valid, process the webhook payload
  console.log('Webhook received:', req.body);
  res.status(200).send('Webhook received and processed.');
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Webhook listener running on port ${PORT}`);
});
How it works: This Node.js Express snippet demonstrates how to securely verify the signature of incoming webhook requests. Many services send a cryptographic signature in a header (e.g., `X-Webhook-Signature`) that is computed using the request's raw body and a shared secret key. This code re-computes the signature on the server-side using the `crypto` module and compares it to the received signature. Using `crypto.timingSafeEqual` is crucial to prevent timing attacks. This verification process ensures that the webhook request is legitimate and has not been tampered with, adding a vital layer of security to your API integrations.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs