JAVASCRIPT

Verifying Webhook Signatures for Secure API Callbacks

Implement robust security for webhook endpoints by verifying request signatures, ensuring incoming data originates from trusted API providers.

const crypto = require('crypto');

function verifyWebhookSignature(payload, signatureHeader, secret) {
  const hmac = crypto.createHmac('sha256', secret);
  hmac.update(payload, 'utf8'); // Ensure payload is a string or Buffer
  const expectedSignature = `sha256=${hmac.digest('hex')}`;

  // Use a timing-safe string comparison to prevent timing attacks
  return crypto.timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(expectedSignature));
}

// Example usage in an Express.js route:
/*
const express = require('express');
const bodyParser = require('body-parser'); // For raw body access
const app = express();
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET || 'your_super_secret_key'; // Replace with your actual secret

// Use raw body parser for webhook endpoints BEFORE any other body parsers
app.use(bodyParser.raw({ type: 'application/json' })); // or other appropriate type for your webhook

app.post('/webhook', (req, res) => {
  const signature = req.headers['x-hub-signature-256'] || req.headers['x-api-signature']; // Check common headers
  if (!signature) {
    return res.status(401).send('No signature provided.');
  }

  try {
    const payload = req.body.toString('utf8'); // Get raw body as string
    if (verifyWebhookSignature(payload, signature, WEBHOOK_SECRET)) {
      const eventData = JSON.parse(payload); // Parse only after verification
      console.log('Webhook verified and received:', eventData);
      res.status(200).send('Webhook received successfully.');
    } else {
      res.status(403).send('Invalid signature.');
    }
  } catch (error) {
    console.error('Error processing webhook:', error);
    res.status(500).send('Internal Server Error.');
  }
});

app.listen(3000, () => console.log('Webhook server listening on port 3000'));
*/
How it works: This Node.js snippet demonstrates how to verify webhook signatures using the `crypto` module. Webhooks often include a signature header (e.g., `X-Hub-Signature`) generated using a shared secret. By re-computing the HMAC signature from the raw request body and comparing it in a timing-safe manner, you can ensure that incoming webhook payloads are legitimate and have not been tampered with, crucial for securing API callbacks.

Need help integrating this into your project?

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

Hire DigitalCodeLabs