From 5398f7afcf017cf480353326cc99911229c0e617 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Thu, 3 Aug 2023 15:57:29 -0600 Subject: [PATCH 1/2] doc(securing-your-webhooks): add standard JavaScript example Adds a JavaScript example that is secure, and follows the WebCrypto standards. --- .../webhooks/securing-your-webhooks.md | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/content/webhooks-and-events/webhooks/securing-your-webhooks.md b/content/webhooks-and-events/webhooks/securing-your-webhooks.md index 4dfb86fdd76e..8c7dd41dc55f 100644 --- a/content/webhooks-and-events/webhooks/securing-your-webhooks.md +++ b/content/webhooks-and-events/webhooks/securing-your-webhooks.md @@ -112,6 +112,57 @@ def verify_signature(payload_body, secret_token, signature_header): raise HTTPException(status_code=403, detail="Request signatures didn't match!") ``` +### JavaScript example + +For example, you can define the following `verifySignature` function and call it in any JavaScript environment - Node.js, Bun, Deno, etc - when you receive a webhook payload: + +```javascript +let encoder = new TextEncoder(); + +async function verifySignature(secret, header, payload) { + let parts = header.split("="); + let sigHex = parts[1]; + + let algorithm = { name: "HMAC", hash: { name: 'SHA-256' } }; + + let keyBytes = encoder.encode(secret); + let extractable = false; + let key = await crypto.subtle.importKey( + "raw", + keyBytes, + algorithm, + extractable, + [ "sign", "verify" ], + ); + + let sigBytes = hexToBytes(sigHex); + let dataBytes = encoder.encode(payload); + let equal = await crypto.subtle.verify( + algorithm.name, + key, + sigBytes, + dataBytes, + ); + + return equal; +} + +function hexToBytes(hex) { + let len = hex.length / 2; + let bytes = new Uint8Array(len); + + let index = 0; + for (let i = 0; i < hex.length; i += 2) { + let c = hex.slice(i, i + 2); + let b = parseInt(c, 16); + bytes[index] = b; + index += 1; + } + + return bytes; +} +``` + ### Typescript example For example, you can define the following `verify_signature` function and call it when you receive a webhook payload: From 96dd75278e2f6bd6758c12f2b2a7bfc3bb576609 Mon Sep 17 00:00:00 2001 From: Sarah Edwards Date: Wed, 9 Aug 2023 18:43:21 -0700 Subject: [PATCH 2/2] Apply suggestions from code review --- content/webhooks-and-events/webhooks/securing-your-webhooks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/webhooks-and-events/webhooks/securing-your-webhooks.md b/content/webhooks-and-events/webhooks/securing-your-webhooks.md index 8c7dd41dc55f..ebda07cb9686 100644 --- a/content/webhooks-and-events/webhooks/securing-your-webhooks.md +++ b/content/webhooks-and-events/webhooks/securing-your-webhooks.md @@ -114,7 +114,7 @@ def verify_signature(payload_body, secret_token, signature_header): ### JavaScript example -For example, you can define the following `verifySignature` function and call it in any JavaScript environment - Node.js, Bun, Deno, etc - when you receive a webhook payload: +For example, you can define the following `verifySignature` function and call it in any JavaScript environment when you receive a webhook payload: ```javascript let encoder = new TextEncoder();