Our Node.js consumer is rejecting valid Genesys Cloud events because the HMAC SHA256 verification fails when we try to block replay attacks. We’re checking the X-Genesys-Signature header against the payload, but the timing window seems too tight or the header format is off. Here’s the verification logic:
const crypto = require('crypto');
const signature = req.headers['x-genesys-signature'];
const timestamp = parseInt(req.headers['x-genesys-timestamp']);
const body = req.body;
if (Date.now() - timestamp > 30000) {
return res.status(401).send('Replay attack suspected');
}
const hmac = crypto.createHmac('sha256', WEBHOOK_SECRET);
hmac.update(`${timestamp}.${body}`);
const expected = hmac.digest('hex');
if (signature !== expected) {
return res.status(403).send('Invalid signature');
}
The signature matches if I remove the timestamp check, but that defeats the purpose. Am I formatting the payload string incorrectly for the HMAC?