Objective - Learn how to verify the HMAC token provided in the MS Teams webhook authorization header to confirm the webhook is genuine.
Example webhook - Authorization header marked in bold at the bottom
{
"method": "post",
"path": "/",
"body": {
"type": "message",
"id": "1648005368373",
"timestamp": "2022-03-29T03:16:08.4051807Z",
"localTimestamp": "2022-03-29T09:46:08.4051807+06:30",
"serviceUrl": "",
"channelId": "msteams",
"from": {
"id": "************************************************",
"name": "Tray_DEMO",
"aadObjectId": "47a1f28c-eaad-4a6e-bb12-605cc0cd047a"
},
"conversation": {
"isGroup": true,
"id": "************************************************",
"name": null,
"conversationType": "channel",
"tenantId": "************************************************"
},
"recipient": null,
"textFormat": "plain",
"attachmentLayout": null,
"membersAdded": [],
"membersRemoved": [],
"topicName": null,
"historyDisclosed": null,
"locale": "en-US",
"text": "<at>webhook</at>\n",
"speak": null,
"inputHint": null,
"summary": null,
"suggestedActions": null,
"attachments": [
{
"contentType": "text/html",
"contentUrl": null,
"content": "<div><div><span itemscope=\"\" itemtype=\"http://schema.skype.com/Mention\" itemid=\"0\">webhook</span></div>\n</div>",
"name": null,
"thumbnailUrl": null
}
],
"entities": [
{
"type": "clientInfo",
"locale": "en-US",
"country": "US",
"platform": "Web",
"timezone": "US/Chicago"
}
],
"channelData": {
"teamsChannelId": "************************************************",
"teamsTeamId": "************************************************",
"channel": {
"id": "************************************************"
},
"team": {
"id": "************************************************"
},
"tenant": {
"id": "************************************************"
}
},
"action": null,
"replyToId": null,
"value": null,
"name": null,
"relatesTo": null,
"code": null,
"localTimezone": "Asia/Rangoon"
},
"query": {},
"headers": {
"accept": "application/json",
"authorization": "HMAC wxS/p6LXGbJqVVbkP8w4e7PmbDF56Z7nOur+OeUcZtY=", <-- Verify this field
"content-length": "1637",
"content-type": "application/json; charset=utf-8",
"host": "c5f589f1-4572-44ad-be18-6b8046b452d3.trayapp.io",
"referer": "https://teams.microsoft.com/",
"x-amzn-trace-id": "Root=1-***************************",
"x-forwarded-for": "*************",
"x-forwarded-port": "443",
"x-forwarded-proto": "https",
"x-ms-request-id": "***********************************",
"x-ms-session-id": "Legacy-Operation-Id-****************"
}
}
Steps
- Stringify the webhook body
- Create a buffer of the secret provided by MS Teams when setting up outgoing webhooks
- Generate the HMAC token
- Prepend 'HMAC ' to the previously generated token
- Compare the generated HMAC token to the token provided in the webhook header
Step 1 - Stringify the webhook body
Add the Object helper connector after the webhook trigger and set the operation to 'JSON stringify'. Use the connector snake to link the Source field to the webhook body_message.
Step 2 - Create a buffer of the secret
After setting up the outgoing webhook. MS Teams will provide you with a security token/secret token similar to the below.
Add the JavaScript connector to your workflow after the stringify step and paste the below script. Replace the 'YOUR_SECRET' value with the secret provided by MS Teams
exports.step = function({foo}, fileInput) {
const secret = 'YOUR_SECRET';
const bufSecret = Buffer.from(secret, "base64");
return bufSecret;
};
Step 3 - Generate the HMAC token
Add the Crypto Helper connector after the previous JavaScript connector step and set the operation to 'HMAC'
- Set the Hash value to SHA256
- Pass the stringified webhook body into the Value field
- Set the Digest encoding to Base64
- Pass in the output of the JavaScript connector to the Secret field
Step 4 - Prepend 'HMAC ' to the previously generated token
Add the Text Helper connector after the previous Crypto Helper connector with the operation set to 'Concatenate'.
- Enter 'HMAC' in the first value field and use the connector snake to link the output of the Crypto helper step to the second value field.
- Enter a single space in the Separator field
Step 5 - Compare the generated HMAC token to the token provided in the webhook header
- Add a Boolean Condition step after the previous Text Helper step.
- Link the first value to the Authorization header provided in the MS Teams webhook.
- Set the comparison step to 'Equal to'.
- Link the second value to the output of the previous Text Helper step.
- If the HMAC values do not match, the workflow should be terminated. If they do match, continue with the workflow.
.
Comments
0 comments
Please sign in to leave a comment.