Last active
September 22, 2023 19:34
-
-
Save phistrom/3d691a2b4845f9ec9421faaebddc0904 to your computer and use it in GitHub Desktop.
Function to verify X-Slack-Signature header in a Cloudflare Worker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* global SLACK_SIGNING_SECRET */ | |
const SIGN_VERSION = 'v0' // per documentation, this is always "v0" | |
/** | |
* Verify that a request actually came from Slack using our Signing Secret | |
* and HMAC-SHA256. | |
* | |
* Based on code examples found in Cloudflare's documentation: | |
* https://developers.cloudflare.com/workers/examples/signing-requests | |
* | |
* @param {Request} request incoming request purportedly from Slack | |
* @returns {Promise<boolean>} true if the signature verification was valid | |
*/ | |
export async function verifySlackSignature(request) { | |
const timestamp = request.headers.get('x-slack-request-timestamp') | |
// remove starting 'v0=' from the signature header | |
const signatureStr = request.headers.get('x-slack-signature').substring(3) | |
// convert the hex string of x-slack-signature header to binary | |
const signature = hexToBytes(signatureStr) | |
const content = await request.text() | |
const authString = `${SIGN_VERSION}:${timestamp}:${content}` | |
let encoder = new TextEncoder() | |
const key = await crypto.subtle.importKey( | |
'raw', | |
encoder.encode(SLACK_SIGNING_SECRET), | |
{ name: 'HMAC', hash: 'SHA-256' }, | |
false, | |
['verify'] | |
) | |
const verified = await crypto.subtle.verify( | |
"HMAC", | |
key, | |
signature, | |
encoder.encode(authString) | |
) | |
return verified | |
} | |
/** | |
* Modified version of hex to bytes function posted here: | |
* https://stackoverflow.com/a/34356351/489667 | |
* | |
* @param {string} hex a string of hexadecimal characters | |
* @returns {ArrayBuffer} binary form of the hexadecimal string | |
*/ | |
function hexToBytes(hex) { | |
const bytes = new Uint8Array(hex.length / 2); | |
for (let c = 0; c < hex.length; c += 2) { | |
bytes[c / 2] = parseInt(hex.substr(c, 2), 16); | |
} | |
return bytes.buffer | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
substr
is deprecated