Fix Insecure Webhooks in Hapi
Webhooks are a prime target for SSRF and unauthorized state manipulation. If your Hapi endpoint blindly accepts POST data without cryptographic verification, you've left a back door open for any attacker to spoof events. In a Hapi environment, the primary failure point is often trusting the parsed JSON instead of the raw payload for signature verification, leading to hash mismatches or bypasses.
The Vulnerable Pattern
server.route({
method: 'POST',
path: '/webhooks/stripe',
handler: (request, h) => {
// VULNERABLE: No signature verification.
// Anyone can POST any JSON to this endpoint.
const event = request.payload;
processOrder(event.data.object.id);
return { received: true };
}
});
The Secure Implementation
To secure Hapi webhooks, you must enforce three things: 1. Raw Payload Access: Set 'payload.parse: false' because verifying a signature against an already-parsed JSON object will fail due to key ordering and whitespace differences. 2. HMAC Verification: Compute a SHA256 HMAC using a shared secret known only to you and the provider. 3. Constant-Time Comparison: Always use 'crypto.timingSafeEqual' when comparing the calculated hash against the provided header to mitigate side-channel timing attacks that could allow an attacker to brute-force the signature.
const crypto = require('crypto');server.route({ method: ‘POST’, path: ‘/webhooks/stripe’, options: { payload: { parse: false, // Essential: Get raw buffer for HMAC output: ‘data’ } }, handler: (request, h) => { const signature = request.headers[‘x-hub-signature-256’]; const secret = process.env.WEBHOOK_SECRET;
if (!signature) return h.response('Missing Signature').code(401); const hmac = crypto.createHmac('sha256', secret); const digest = Buffer.from('sha256=' + hmac.update(request.payload).digest('hex'), 'utf8'); const checksum = Buffer.from(signature, 'utf8'); // Use timingSafeEqual to prevent timing attacks if (checksum.length !== digest.length || !crypto.timingSafeEqual(digest, checksum)) { return h.response('Invalid Signature').code(401); } const payload = JSON.parse(request.payload.toString()); processOrder(payload.id); return { verified: true };
} });
Your Hapi API
might be exposed to Insecure Webhooks
74% of Hapi apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.