Mandrill Webhook - 安全性
Posted
技术标签:
【中文标题】Mandrill Webhook - 安全性【英文标题】:Mandrill Webhooks - Security 【发布时间】:2013-04-20 11:19:33 【问题描述】:出于安全考虑,我尝试只允许 Mandrill 的 IP 访问这些 url。
有人认识他们吗?
【问题讨论】:
【参考方案1】:Mandrill 的签名位于 HTTP 响应头中:Authenticating-webhook-requests
在请求头中找到:X-Mandrill-Signature
。这是哈希码的 base64,使用 web-hook 密钥签名。此密钥仅对您的 webhook 保密。
【讨论】:
【参考方案2】:我们有一系列用于 webhook 的 IP,但随着我们的扩展,它们可以(并且可能会)更改或添加新的 IP。另一种方法是将查询字符串添加到您在 Mandrill 中添加的 webhook URL,然后在 POST 进入时检查该查询字符串,以便验证它来自 Mandrill。
【讨论】:
哦,是的,好主意。对于其他人,它是关于元数据信息的。这是一个码头,我现在不喜欢你的帖子:)。谢谢 不能欺骗IP! @ankitjaininfo 偶然发现了这个问题,你的评论激起了我的好奇心。我的第一直觉是“不容易”。然后我在 IT Security Stack Exchange 上找到了这篇文章:security.stackexchange.com/questions/14505/…。我猜,迟到 3 年总比没有好。【参考方案3】:只需替换常量并使用此功能:
<?php
function generateSignature($post)
$signed_data = WEB_HOOK_URL;
ksort($post);
foreach ($post as $key => $value)
$signed_data .= $key;
$signed_data .= $value;
return base64_encode(hash_hmac('sha1', $signed_data, WEB_HOOK_AUTH_KEY, true));
//---
if (generateSignature($_POST) != $_SERVER['HTTP_X_MANDRILL_SIGNATURE'])
//Invalid
?>
【讨论】:
【参考方案4】:正如 mandrill 的 docs 中所述,它们提供了一个签名来检查请求是否真的来自它们。构建请求有几个步骤:
-
从您的 webhook 的确切 url 开始(注意斜线和参数)
按键排序后变量(如果是 mandrill,您将只有一个后参数:
mandrill_events
)
在url中添加key和value,不带任何分隔符
使用您的密钥(您可以从 Web 界面获取密钥)和 base64 对 url 进行 hmac 处理。
将结果与X-Mandrill-Signature
标头进行比较
这里是python中的一个示例实现:
import hmac, hashlib
def check_mailchimp_signature(params, url, key):
signature = hmac.new(key, url, hashlib.sha1)
for key in sorted(params):
signature.update(key)
signature.update(params[key])
return signature.digest().encode("base64").rstrip("\n")
【讨论】:
【参考方案5】:205.201.136.0/16
我刚刚在我的服务器防火墙中将它们列入白名单。
【讨论】:
【参考方案6】:我们不需要将他们使用的 IP 列入白名单。相反,他们提供了自己的方式来验证 webhook 请求。
当您创建 mandrill webhook 时,它将生成密钥。它将来自我们对 webhook 中提供的帖子 URL 的响应。
public async Task<IHttpActionResult> MandrillEmailWebhookResponse()
string mandrillEvents = HttpContext.Current.Request.Form["mandrill_events"].Replace("mandrill_events=", "");
// validate the request is coming from mandrill API
string url = ConfigurationManager.AppSettings["mandrillWebhookUrl"];
string MandrillKey = ConfigurationManager.AppSettings["mandrillWebHookKey"];
url += "mandrill_events";
url += mandrillEvents;
byte[] byteKey = System.Text.Encoding.ASCII.GetBytes(MandrillKey);
byte[] byteValue = System.Text.Encoding.ASCII.GetBytes(url);
HMACSHA1 myhmacsha1 = new HMACSHA1(byteKey);
byte[] hashValue = myhmacsha1.ComputeHash(byteValue);
string generatedSignature = Convert.ToBase64String(hashValue);
string mandrillSignature = HttpContext.Current.Request.Headers["X-Mandrill-Signature"].ToString();
if (generatedSignature == mandrillSignature)
// validation = "Validation successful";
// do the updating using the response data
【讨论】:
以上是关于Mandrill Webhook - 安全性的主要内容,如果未能解决你的问题,请参考以下文章
从 Mandrill Webhook 接收到的 JSON 字符串无效
将 Mandrill JSON webhook 入站电子邮件附件映射到 C# 类
如何在 .net 中处理 Mandrill WebHooks