Created
April 23, 2024 23:31
Mailgun Webhook: validate webhook request in Python
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
# https://documentation.mailgun.com/docs/mailgun/user-manual/tracking-messages/#webhooks | |
# Securing Webhooks | |
# To ensure the authenticity of event requests, Mailgun signs them and posts the signature alongside the webhook's event-data. | |
# A signature takes the following form: | |
# Parameter Type Description | |
# timestamp int Number of seconds passed since January 1, 1970. | |
# token string Randomly generated string with length of 50. | |
# signature string String with hexadecimal digits generated by an HMAC algorithm | |
# To verify the webhook originated from Mailgun, you will need to: | |
# Concatenate timestamp and token values together with no separator. | |
# Encode the resulting string with the HMAC algorithm, using your Webhook Signing Key as a key and SHA256 digest mode. | |
# Compare the resulting hexdigest to the signature. If they do not match then the webhook is not from Mailgun! | |
import hmac, hashlib | |
# Look for HTTP webhook signing key in your Mailgun panel | |
WEBHOOK_SIGNING_KEY = b"key-xxx" | |
def verify(token, timestamp, signature): | |
hmac_digest = hmac.new( | |
key=WEBHOOK_SIGNING_KEY, | |
msg="{}{}".format(timestamp, token).encode("utf-8"), | |
digestmod=hashlib.sha256, | |
).hexdigest() | |
return hmac.compare_digest(signature, hmac_digest) | |
# Mailgun's POST request will have "signature" in the payload, there you'll find | |
# "token", "timestamp" and "signature" fields, like so: | |
# { | |
# "token": "xxx", | |
# "timestamp": "yyy", | |
# "signature": "zzz" | |
# } | |
print(verify("xxx", "yyy", "zzz")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment