希望有人能告诉我我在这里做错了什么。
我设置了一个 Discourse Webhook,在没有 Secret 的情况下,它的工作符合预期。然后,我在 Secret 中写入一个字符串,然后像这样将该字符串复制到接收 Webhook 的 Header 中:
X-Discourse-Event-Signature: secret_here
当发送 Webhook 发送时,这会在 Body 中产生以下错误:
{"code":"rest_forbidden","message":"Sorry, you are not allowed to do that.","data":{"status":401}}
我猜是我没有正确操作,所以请指教!
我知道 Secret 使用 sha256 进行加密,所以发送的 Header 是:
X-Discourse-Event-Signature: sha256=XXX
但我不知道在接收 Webhook 的安全 Header 中应该如何处理这些信息。
RGJ
(Richard - Communiteq)
2
我不确定这只是你写帖子的方式,但实际的标头应该是
X-Discourse-Event-Signature: XXX
你可以在接收端(可选地)使用它来验证 webhook 是否确实由 Discourse 发送。如果你不进行验证,那么恶意方可能会伪造 webhook 事件。
这是什么意思?
1 个赞
所以你的建议是接收 webhook 中的 Signature 应该是加密后的 secret,而不是未加密的选定 secret?
我确实是这样在接收应用程序中编写 Header 的:
X-Discourse-Event-Signature: XXX
但是,当我使用 Secret 时,我一直收到 401 禁止访问错误。
RGJ
(Richard - Communiteq)
4
截图来自哪里?
也许你可以更详细地介绍一下你的设置。
我的 Wordpress 网站。我正在使用一个 Wordpress 插件来接收 Webhooks。如果我不添加安全标头(Secret),Webhook 可以正常工作。只有当我添加 Secret 时,问题才会出现。
这是插件:Incoming Webhook Triggers - Uncanny Automator
感谢您的时间和 Richard!
1 个赞
我后来缩小了问题范围:
传入的 webhook 触发器可能包含自定义安全标头,但有一个重要说明是 WordPress 如何将连字符更改为下划线。例如,尝试使用“x-api-key”可能需要改用“x_api_key”。
不过,我有一个相关问题 @RGJ。假设我的密钥是“1234”。在接收的 webhook 中,X-Discourse-Event-Signature 的值应该是:
- 1234;
- sha256=encrypted_value_here;
- encrypted_value_here
?
RGJ
(Richard - Communiteq)
7
它是#2,sha256=XXX。
看起来您正在使用的WordPress插件只能与静态标头值进行比较,而不能与动态签名进行比较。这是Discourse特有的东西。
1 个赞
simon
8
看看WP Discourse插件是如何处理密钥的:
5 个赞
我后来发现,每次发送 webhook 时 sha 值都会改变,所以将 sha 值放在接收 webhook 中是行不通的。我认为它必须是示例 #1,而且正如您可能建议的那样(重新静态标头),插件实际上是否需要在生成标头响应之前解码哈希?
总之,我认为我无法在此插件中使用哈希的 X-Discourse-Event-Signature,因为它只接受静态值。
使用没有 Secret 的 webhook 是否不安全?我将从我的 Discourse 发送用户事件到我的主网站,使用一个不明显的 URL,例如 main-site.com/wp-json/fol/fil/532563-5312534。我还可以添加必须在接收钩子上匹配的静态标头。
您能否给我一个可以处理动态变化的 hmac 的应用程序示例?
simon
10
该值是根据 webhook 的 payload 计算的,因此每次请求都会不同。
这是一个有趣的问题。我所知道的唯一应用程序是 WP Discourse 插件,但它是专门配置来处理 Discourse webhook 的。如果 Discourse 的实现阻止人们使用 secret 验证 webhook,那么可能需要对此进行调查。
我将把这个问题留给其他人来回答。
如果您担心不验证 webhook,那么 Incoming Webhook Triggers 插件在其接收 webhook 的代码中可能有一个操作钩子,该钩子在处理 webhook 数据之前触发。如果存在,应该可以编写一个函数来挂接到它,检查数据是否是 Discourse webhook 的,然后使用我之前帖子中链接的代码之类的东西来验证 secret。
2 个赞
simon
11
我很好奇,所以对此进行了一些研究。我不确定有哪些应用程序被配置为处理_接收_动态HMAC签名,但使用针对负载计算的HMAC签名来验证Webhook请求,对于_发送_Webhook的应用程序来说是一种相当标准的做法。例如,GitHub、Stripe和Shopify都使用这种方法。
还有相当多的流行应用程序使用秘密令牌方法来验证Webhook。例如(截至2021年),Mailchimp、Trello、Slack和Discord都采用了这种方法。看起来Slack仍在沿用这种方法:Slack developer FAQ | Slack Developer Docs
我想在安全性和便利性之间进行权衡,以决定发送方应用程序将使用哪种方法。我对Discourse的HMAC签名方法感到担忧,因为它可能会导致人们为了绕过处理动态HMAC签名的困难而配置没有密钥的Webhook。例如,在Meta上有一些关于将Discourse Webhook发送到Zapier的参考,但没有提到如何在Zapier上验证签名。(尽管在技术上应该可以在Zapier上验证签名。我目前没有设置来测试这一点。)
2 个赞
我完全同意这一点。也许这是开发人员可以探索的事情——一种更简单、更兼容的方法来保护网络钩子数据。
另外,我不太确定 Zapier 是否有能力验证签名。
Falco
(Falco)
13
Webhook 密钥功能是根据以下内容实现的:
您想要的软件似乎不支持此标准安全通信功能,但您仍然可以不使用它来利用 Discourse Webhooks。
没有计划添加带有共享密钥的固定标头,因为其安全价值值得怀疑。但是,如果您需要此功能,应该可以在插件中实现。
4 个赞