Two inbound webhook handlers compare the signature/hash with a plain !==, which is not constant-time (CWE-208, timing side channel). The project already uses the correct pattern (crypto.timingSafeEqual) in the Intercom handler, so this is a consistency fix.
Locations (at commit cd857be)
apps/web/app/(ee)/api/shopify/integration/webhook/route.ts:38
if (generatedSignature !== signature) { ... }
apps/web/app/(ee)/api/hubspot/webhook/route.ts:39
if (signature !== expectedHash) { ... }
Reference pattern already in the repo
apps/web/app/(ee)/api/intercom/webhook/verify-webhook-signature.ts (around lines 57-67):
if (providedBuffer.length !== expectedBuffer.length) { throw ...; }
const isSignatureValid = crypto.timingSafeEqual(
Uint8Array.from(providedBuffer),
Uint8Array.from(expectedBuffer),
);
Suggested change
Mirror the Intercom approach in the Shopify and HubSpot handlers: compare the raw bytes with a length pre-check and crypto.timingSafeEqual instead of !==.
Severity
Low. Timing attacks against an HMAC comparison over the network are hard to exploit in practice due to jitter; this is defense-in-depth / consistency, not a reported vulnerability. No proof-of-concept.
Two inbound webhook handlers compare the signature/hash with a plain
!==, which is not constant-time (CWE-208, timing side channel). The project already uses the correct pattern (crypto.timingSafeEqual) in the Intercom handler, so this is a consistency fix.Locations (at commit
cd857be)apps/web/app/(ee)/api/shopify/integration/webhook/route.ts:38apps/web/app/(ee)/api/hubspot/webhook/route.ts:39Reference pattern already in the repo
apps/web/app/(ee)/api/intercom/webhook/verify-webhook-signature.ts(around lines 57-67):Suggested change
Mirror the Intercom approach in the Shopify and HubSpot handlers: compare the raw bytes with a length pre-check and
crypto.timingSafeEqualinstead of!==.Severity
Low. Timing attacks against an HMAC comparison over the network are hard to exploit in practice due to jitter; this is defense-in-depth / consistency, not a reported vulnerability. No proof-of-concept.