secure-express-setup
Version:
Military-grade one-command security setup for Express.js applications
32 lines (24 loc) • 1.42 kB
JavaScript
// lib/webhookSignature.js
const crypto = require('crypto');
function setupWebhookSignature({ secret, headerName = 'x-signature', algorithm = 'sha256', rawBody = true } = {}) {
if (!secret) throw new Error('webhook secret required');
return function verifyWebhook(req, res, next) {
try {
// Ensure raw body is available (express needs middleware to keep raw body)
// If using express.json(), you can capture raw body via a custom body parser.
const signatureHeader = (req.headers[headerName] || '').trim();
if (!signatureHeader) return res.status(400).json({ error: 'Missing signature header' });
const received = signatureHeader.startsWith(`${algorithm}=`) ? signatureHeader.split('=')[1] : signatureHeader;
const payload = rawBody && req.rawBody ? req.rawBody : (typeof req.body === 'string' ? req.body : JSON.stringify(req.body || {}));
const hmac = crypto.createHmac(algorithm, secret).update(payload).digest('hex');
// Use a constant-time compare
const valid = crypto.timingSafeEqual(Buffer.from(hmac), Buffer.from(received));
if (!valid) return res.status(401).json({ error: 'Invalid signature' });
next();
} catch (err) {
console.error('Webhook signature verification error:', err);
res.status(500).json({ error: 'Internal error' });
}
};
}
module.exports = setupWebhookSignature;