If you’re building a Slack app in Python, you’ll need to verify that the inbound callbacks you’re receiving are genuine.
This page in the Slack API docs explains the process in pseudocode: Verifying requests from Slack
Below is a Python function, based on that pseudocode, which will simply return True if the request is valid, and False if not. This has been tested using a Flask request object, but should be easily adaptable to any other web framework.
I’ve declared the secrets in code here for ease of the example, but you shouldn’t do this in real life. You should put your secrets somewhere outside of the code (e.g. environment variables) and read them from config when needed.
import hmac import hashlib import time def verify_request(request): SIGNING_SECRET = "your_slack_signing_secret" # Convert your signing secret to bytes slack_signing_secret = bytes(SIGNING_SECRET, "utf-8") request_body = request.get_data().decode() slack_request_timestamp = request.headers["X-Slack-Request-Timestamp"] slack_signature = request.headers["X-Slack-Signature"] # Check that the request is no more than 60 seconds old if (int(time.time()) - int(slack_request_timestamp)) > 60: print("Verification failed. Request is out of date.") return False # Create a basestring by concatenating the version, the request timestamp, and the request body basestring = f"v0:{slack_request_timestamp}:{request_body}".encode("utf-8") # Hash the basestring using your signing secret, take the hex digest, and prefix with the version number my_signature = ( "v0=" + hmac.new(slack_signing_secret, basestring, hashlib.sha256).hexdigest() ) # Compare the resulting signature with the signature on the request to verify the request if hmac.compare_digest(my_signature, slack_signature): return True else: print("Verification failed. Signature invalid.") return False
This could also be implemented as a Python decorator (if I get a chance I’ll update this post with an example of that too).
Thanks for this! I’m building a Slack bot at the moment and thought this was going to be a pain but you’ve taken all the trouble away 🙂
For anyone else reading this – don’t store your secrets in code! Read from an environmental variable or retrieve from a secret store somewhere.
Thanks – and yes I should update the post to make it clear you shouldn’t put the secrets in code in real life 🙂
You can also use the SignatureVerifier from the python slack sdk here
https://github.com/slackapi/python-slack-sdk/blob/main/slack_sdk/signature/__init__.py#L24