I’m not sure if this is just the way you are writing the post but the actual header would be
You can (optionally) use this at the receiving end to validate that the webhook was actually sent by Discourse. If you don’t do the verification then a malicious party could potentially forge webhook events.
Custom security headers may be included in the incoming webhook trigger, but one important note is how WordPress can change dashes to underscores. As an example, trying to use “x-api-key” may require using “x_api_key” instead.
I do however have a related question though @RGJ . Let’s say my secret is “1234”. In the receiving webhook, should the X-Discourse-Event-Signature value be:
I’ve since discovered that the sha value changes every time the webhook is sent, so putting the sha value in the receiving webhook would not work. I would think it would have to be example #1, and as I think you’re suggesting (re-static header), the plugin would actually need to decode the hash before generating the header response?
In conclusion, I don’t think I can use the hashed X-Discourse-Event-Signature in this plugin, because it will only accept static values.
Is it unsafe to use a webhook without a Secret? I would be sending User Events from my Discourse to my main website, using a non-obvious url such as main-site.com/wp-json/fol/fil/532563-5312534 . I can also add static headers that must match on the receiving hook.
Could you give me an example of an application that could handle a dynamically changing hmac ?
The value is calculated against the webhook’s payload, so it’s going to be different for every request.
That’s an interesting question. The only application I know of is the WP Discourse plugin, but it was configured specifically to handle Discourse webhooks. If Discourse’s implementation is preventing people from validating webhooks with secrets, maybe that needs to be looked into.
I’ll leave that for others to answer.
If you are concerned about not validating the webhook, maybe the Incoming Webhook Triggers plugin has an action hook in its webhook receiving code that’s fired before the webhook’s data is processed. If it does, it should be possible to write a function that hooks into it, checks to see if the data is for a Discourse webhook, then validates the secret with something like the code I linked to in my previous post.
I was curious, so I looked into this a bit. I’m unsure about applications that are configured to handle receiving a dynamically changing HMAC signature, but authenticating webhook requests with a HMAC signature that’s calculated against the payload is a fairly standard practice for applications that are sending webhooks. For example, GitHub, Stripe, and Shopify all use this method.
There are also quite a few popular applications that use the secret token method of authenticating webhooks. For example (as of 2021) Mailchimp, Trello, Slack, and Discord all use this approach. It seems that Slack is still using this method: FAQ | Slack. I can see how that would make things easier for the application that receives the webhook.
I guess there’s a trade off between security and convenience in terms of deciding which method the sending application will use. My concern with Discourse’s HMAC signature method is that it might result in people configuring webhooks without secret keys in order to get around the difficulty of handling the changing HMAC signatures. For example, there are a few references on Meta for sending Discourse webhooks to Zapier without any mention of how to validate the signature on Zapier. (It should be technically possible to validate the signatures on Zapier though. I’m not setup to test that at the moment.)