diff --git a/resources/webhooks.ts b/resources/webhooks.ts index 29c96d4c..fd30c9c8 100644 --- a/resources/webhooks.ts +++ b/resources/webhooks.ts @@ -42,9 +42,11 @@ export class Webhooks extends BaseResource { } public verify(signature: string, secret: string, payload: any) { + const signatureBuffer = Buffer.from(signature, "base64") const hmac = crypto.createHmac("sha1", secret) hmac.update(JSON.stringify(payload)) - return hmac.digest("base64") == signature + + return crypto.timingSafeEqual(hmac.digest(), signatureBuffer) } } diff --git a/tests/webhooks.spec.ts b/tests/webhooks.spec.ts index 5abb3f1c..e7032203 100644 --- a/tests/webhooks.spec.ts +++ b/tests/webhooks.spec.ts @@ -22,4 +22,15 @@ describe("Get Webhook Test", () => { expect(res.data.type === "webhook").toBeTruthy() }) }) +}) + +describe("Verify Webhook test", () => { + test("verify webhook signature", () => { + const signature = "UUNz8ch1Ovjg+ijXUEwlAlWEktU=" + const secret = "OB2HL5E3B4HJ7IVXRNL4YQKYIQIVJK36ZZLPZEFWZVSDSC7LLFJQ====" + const payload = {"data":[{"id":"46306092","type":"application.approved","attributes":{"createdAt":"2025-08-05T06:48:38.957Z","tags":{"key":"another-tag","test":"webhook-tag","number":"111"}},"relationships":{"application":{"data":{"id":"3895367","type":"individualApplication"}},"customer":{"data":{"id":"3310133","type":"individualCustomer"}}}}]} + + const verifyResult = unit.webhooks.verify(signature, secret, payload) + expect(verifyResult).toBeTruthy() + }) }) \ No newline at end of file