Webhook Signature Verification
Learn how to verify webhook authenticity using HMAC-SHA256 signatures to secure your integration.
Why Verify Signatures?
Without signature verification, anyone could send fake webhook requests to your server, potentially:
- Crediting accounts without payment
- Triggering fraudulent order fulfillment
- Manipulating your business logic
Always verify signatures to ensure requests genuinely came from BlockEden.xyz.
How It Works
BlockEden.xyz signs every webhook request using HMAC-SHA256:
signature = HMAC-SHA256(your_webhook_secret, raw_request_body)
The signature is sent in the x-eden-signature HTTP header. Your server must:
- Read the raw request body (before parsing)
- Compute the expected signature using your secret
- Compare it with the received signature
- Only process the event if signatures match
Implementation Guide
Node.js with Express
const express = require('express');
const crypto = require('crypto');
const app = express();
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;
function verifyWebhookSignature(body, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
// Use constant-time comparison to prevent timing attacks
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// IMPORTANT: Use express.raw() to get the raw body
app.post('/api/webhooks',
express.raw({ type: 'application/json' }),
(req, res) => {
const signature = req.headers['x-eden-signature'];
if (!signature) {
console.error('<ion-icon name="close-circle" style={{verticalAlign: "middle", fontSize: "1.2em", color: "#ef4444"}}></ion-icon> Missing signature header');
return res.status(401).send('Missing signature');
}
if (!verifyWebhookSignature(req.body, signature, WEBHOOK_SECRET)) {
console.error('<ion-icon name="close-circle" style={{verticalAlign: "middle", fontSize: "1.2em", color: "#ef4444"}}></ion-icon> Invalid signature');
return res.status(401).send('Invalid signature');
}
// Signature valid - safe to process
const event = JSON.parse(req.body.toString());
console.log('<ion-icon name="checkmark-circle" style={{verticalAlign: "middle", fontSize: "1.2em", color: "#10b981"}}></ion-icon> Signature verified for event:', event.type);
// Process event...
res.status(200).json({ received: true });
}
);
app.listen(3000);