ASP.Net MVC cookies - 防篡改?
ASP.Net MVC cookies - tamper resistant?
所以我正在阅读我在 /r/netsec 上找到的一篇简洁的文章:
https://paragonie.com/blog/2015/05/using-encryption-and-authentication-correctly
真正让我陷入困境的一件事是,可以在加密的 cookie 中稍微翻转一下,实际上会对包含的数据进行有意义的更改。
确保所有流量都通过 SSL 很容易(这不是关于安全传输的问题),但这让我真正开始思考消息完整性以及如何查看原始 cookie 是否已被篡改。通常我只会将经过身份验证的用户 ID 存储在 cookie 中,并在我的防火墙后面处理所有其他内容。如果我可以篡改该 cookie 以从客户端更改用户 ID 怎么办?上面的文章表明这是可能的,并提供了使用 libsodium 解决此问题的建议。我知道这个库(我自己没用过),但这让我进一步陷入困境,认为需要 ASP 内置安全机制之外的东西。
具体关于内置 ASP 安全性,我是否需要做任何尚未以处理 cookie 安全性的标准方式实现的特殊操作(让 OWIN 做它的事情或使用 FormsAuthentication.Encrypt)?如果不是,消息完整性是如何处理的?
进一步阅读使我在代码项目上找到了这个 HttpSecureCookie class:
http://www.codeproject.com/Articles/13665/HttpSecureCookie-A-Way-to-Encrypt-Cookies-with-ASP
上面说的是使用机器密钥来做cookie防篡改,但是我不清楚具体是如何做到防篡改的。这将如何防止恶意用户将原始文章中指示的位翻转到加密的 cookie?
只需将 forms authentication protection 方法设置为 Encryption and validation
。
这将防止位翻转攻击,因为一旦位被翻转,签名将不匹配。验证意味着消息已签名。
验证是如何工作的?
验证算法can be set in web.config
in the validationAlgorithm
attribute of the machineKey
element.
默认情况下,它使用 HMACSHA256,这是一个 SHA-256 hash applied using the HMAC 结构。
哈希对 cookie 进行签名 - 如果 cookie 值发生变化,哈希将不再匹配。由于最终用户不知道这个秘密,他们无法更改 cookie 值。
例如尝试 on here 为消息 foo
使用秘密 secret
.
生成 SHA-256 HMAC
这应该给你:773ba44693c7553d6ee20f61ea5d2757a9a4f4a44d2841ae4e95b52e4cd62db4
请注意,如果您将 foo
更改为其他内容,则哈希值会有所不同。这就是防止 cookie 被篡改的方法。此 cookie 将设置如下。
Set-Cookie: id=foo&hash=773ba44693c7553d6ee20f61ea5d2757a9a4f4a44d2841ae4e95b52e4cd62db4
请注意,该值是明文的,但哈希签名可防止任何篡改。这只是验证。
使用加密和验证选项 foo
将首先加密,签名将防止任何位翻转。这使得最终用户可以私密地存储值。
如果您在 Forms 身份验证之外实现此功能,请记住在 cookie 中存储某种类型的到期日期并将其包含在签名中。这个日期可以在服务器端检查。默认情况下,表单身份验证会执行此操作。
否则,用户可能会记下有效的 cookie 值。假设他们获得了一天的管理员访问权限并发出了以下 cookie:
username=admin&hash=71b3ba92493e92ce3c60042988e9de428f44b35a6be61c8da99fa43f950d3056
当管理员权限被撤销的第二天,用户需要做的就是使用 cookie 编辑器将他们的 cookie 设置为上述值,他们将再次拥有系统的管理员权限。
要解决这个问题,您可以像这样发出一个 cookie:
username=admin&expiry=20150508100000&hash=e38a3a003b30ceb9060165d19bb8d2a2bca6c7c531a37e888448ca417166db3a
这在 cookie 中有到期日期,在哈希中签名。任何修改到期日期的尝试都将导致 HMAC 不匹配,并且用户将无法访问。这将防止任何篡改 cookie 到期日期或任何娱乐客户端。
What are our other don't-mess-with-my-cookie options if not using forms authentication?
另一种方法是存储一个完全随机的、加密安全的生成字符串并将其设置为 cookie 值。在您的服务器上,将其存储为使用 SHA-2 散列(无需加盐)并查找此值以检索有关用户会话的详细信息。当然这有更多的开销。优点是可以通过删除条目在服务器端终止会话。
这也可以通过表单身份验证来完成,但是您需要实施自定义提供程序。
所以我正在阅读我在 /r/netsec 上找到的一篇简洁的文章:
https://paragonie.com/blog/2015/05/using-encryption-and-authentication-correctly
真正让我陷入困境的一件事是,可以在加密的 cookie 中稍微翻转一下,实际上会对包含的数据进行有意义的更改。
确保所有流量都通过 SSL 很容易(这不是关于安全传输的问题),但这让我真正开始思考消息完整性以及如何查看原始 cookie 是否已被篡改。通常我只会将经过身份验证的用户 ID 存储在 cookie 中,并在我的防火墙后面处理所有其他内容。如果我可以篡改该 cookie 以从客户端更改用户 ID 怎么办?上面的文章表明这是可能的,并提供了使用 libsodium 解决此问题的建议。我知道这个库(我自己没用过),但这让我进一步陷入困境,认为需要 ASP 内置安全机制之外的东西。
具体关于内置 ASP 安全性,我是否需要做任何尚未以处理 cookie 安全性的标准方式实现的特殊操作(让 OWIN 做它的事情或使用 FormsAuthentication.Encrypt)?如果不是,消息完整性是如何处理的?
进一步阅读使我在代码项目上找到了这个 HttpSecureCookie class: http://www.codeproject.com/Articles/13665/HttpSecureCookie-A-Way-to-Encrypt-Cookies-with-ASP
上面说的是使用机器密钥来做cookie防篡改,但是我不清楚具体是如何做到防篡改的。这将如何防止恶意用户将原始文章中指示的位翻转到加密的 cookie?
只需将 forms authentication protection 方法设置为 Encryption and validation
。
这将防止位翻转攻击,因为一旦位被翻转,签名将不匹配。验证意味着消息已签名。
验证是如何工作的?
验证算法can be set in web.config
in the validationAlgorithm
attribute of the machineKey
element.
默认情况下,它使用 HMACSHA256,这是一个 SHA-256 hash applied using the HMAC 结构。
哈希对 cookie 进行签名 - 如果 cookie 值发生变化,哈希将不再匹配。由于最终用户不知道这个秘密,他们无法更改 cookie 值。
例如尝试 on here 为消息 foo
使用秘密 secret
.
这应该给你:773ba44693c7553d6ee20f61ea5d2757a9a4f4a44d2841ae4e95b52e4cd62db4
请注意,如果您将 foo
更改为其他内容,则哈希值会有所不同。这就是防止 cookie 被篡改的方法。此 cookie 将设置如下。
Set-Cookie: id=foo&hash=773ba44693c7553d6ee20f61ea5d2757a9a4f4a44d2841ae4e95b52e4cd62db4
请注意,该值是明文的,但哈希签名可防止任何篡改。这只是验证。
使用加密和验证选项 foo
将首先加密,签名将防止任何位翻转。这使得最终用户可以私密地存储值。
如果您在 Forms 身份验证之外实现此功能,请记住在 cookie 中存储某种类型的到期日期并将其包含在签名中。这个日期可以在服务器端检查。默认情况下,表单身份验证会执行此操作。
否则,用户可能会记下有效的 cookie 值。假设他们获得了一天的管理员访问权限并发出了以下 cookie:
username=admin&hash=71b3ba92493e92ce3c60042988e9de428f44b35a6be61c8da99fa43f950d3056
当管理员权限被撤销的第二天,用户需要做的就是使用 cookie 编辑器将他们的 cookie 设置为上述值,他们将再次拥有系统的管理员权限。
要解决这个问题,您可以像这样发出一个 cookie:
username=admin&expiry=20150508100000&hash=e38a3a003b30ceb9060165d19bb8d2a2bca6c7c531a37e888448ca417166db3a
这在 cookie 中有到期日期,在哈希中签名。任何修改到期日期的尝试都将导致 HMAC 不匹配,并且用户将无法访问。这将防止任何篡改 cookie 到期日期或任何娱乐客户端。
What are our other don't-mess-with-my-cookie options if not using forms authentication?
另一种方法是存储一个完全随机的、加密安全的生成字符串并将其设置为 cookie 值。在您的服务器上,将其存储为使用 SHA-2 散列(无需加盐)并查找此值以检索有关用户会话的详细信息。当然这有更多的开销。优点是可以通过删除条目在服务器端终止会话。
这也可以通过表单身份验证来完成,但是您需要实施自定义提供程序。