From f7d622d3dbb37ea55a04b3ffc73f8783fbbb8543 Mon Sep 17 00:00:00 2001 From: Radoslav Georgiev Date: Sat, 24 Jul 2021 17:22:57 +0300 Subject: [PATCH] Add Slack request verification --- solution/main.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/solution/main.py b/solution/main.py index cf9dd7b..359f079 100644 --- a/solution/main.py +++ b/solution/main.py @@ -1,3 +1,6 @@ +import hmac +import hashlib + from pprint import pprint import requests @@ -6,7 +9,7 @@ from dotenv import dotenv_values -from fastapi import Body, FastAPI, Request, Response +from fastapi import Body, FastAPI, Request, Response, status config = dotenv_values(".env") @@ -16,6 +19,19 @@ # This token can be obtained from the `OAuth Tokens for Your Workspace` section # In `OAuth & Permissions` in the bot settings BOT_TOKEN = config["BOT_TOKEN"] +SIGNING_SECRET = config["SIGNING_SECRET"] + + +def slack_validate_request(timestamp, body, slack_signature): + sig_basestring = 'v0:' + timestamp + ':' + body + + signature = 'v0=' + hmac.new( + SIGNING_SECRET.encode(), + sig_basestring.encode(), + hashlib.sha256 + ).hexdigest() + + return signature == slack_signature @app.post("/echo") @@ -23,6 +39,17 @@ async def echo(request: Request, response: Response, data=Body(...)): raw_body = await request.body() body = raw_body.decode("utf-8") + # We are following the guide from here: + # https://api.slack.com/authentication/verifying-requests-from-slack + slack_timestamp = request.headers['x-slack-request-timestamp'] + slack_signature = request.headers['x-slack-signature'] + + is_valid = slack_validate_request(slack_timestamp, body, slack_signature) + + if not is_valid: + response.status_code = status.HTTP_403_FORBIDDEN + return + # We need to add the `channels:read` scope # From the `OAuth & Permissions` section in the bot settings # This will give us `data.event.channel`, which is the channe id,