GuardAPI Logo
GuardAPI

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 };

} });

System Alert • ID: 5669
Target: Hapi API
Potential Vulnerability

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.

RUN FREE SECURITY DIAGNOSTIC
GuardLabs Engine: ONLINE

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.