JAVASCRIPT

Verify Webhook Signatures in Node.js for Security

Learn to secure your Node.js webhook endpoints by verifying incoming request signatures, ensuring data integrity and preventing unauthorized requests.

const crypto = require('crypto');

// Your secret key for webhook verification (should be stored securely, e.g., environment variable)
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET || 'your_super_secret_key';

function verifyWebhookSignature(req, res, next) {
  const signature = req.headers['x-hub-signature-256'] || req.headers['webhook-signature'];
  if (!signature) {
    console.warn('Webhook signature missing.');
    return res.status(401).send('Unauthorized: Signature missing');
  }

  // Ensure raw body is available. For Express, use `express.raw({type: '*/*'})` middleware.
  const rawBody = req.rawBody; 
  if (!rawBody) {
    console.error('Raw body not available for signature verification.');
    return res.status(500).send('Internal Server Error: Raw body missing.');
  }

  const hmac = crypto.createHmac('sha256', WEBHOOK_SECRET);
  const digest = hmac.update(rawBody).digest('hex');
  const expectedSignature = `sha256=${digest}`;

  if (crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature))) {
    console.log('Webhook signature verified successfully.');
    next();
  } else {
    console.warn('Webhook signature verification failed.');
    return res.status(403).send('Forbidden: Invalid signature');
  }
}

// Example Express.js usage:
// const express = require('express');
// const bodyParser = require('body-parser');
// const app = express();

// app.use(bodyParser.json({ verify: (req, res, buf) => { req.rawBody = buf; } })); // Make raw body available

// app.post('/webhook', verifyWebhookSignature, (req, res) => {
//   console.log('Received verified webhook payload:', req.body);
//   res.status(200).send('Webhook received and processed.');
// });

// app.listen(3000, () => console.log('Server running on port 3000'));
How it works: This Node.js snippet demonstrates how to verify webhook signatures, a critical security measure when receiving data from third-party APIs (e.g., Stripe, GitHub). By comparing a computed hash of the incoming request body with the signature provided in the request headers (using a shared secret key), you can confirm that the webhook originated from a legitimate source and that its payload has not been tampered with during transit. This prevents unauthorized entities from sending forged or malicious data to your endpoints.

Need help integrating this into your project?

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

Hire DigitalCodeLabs