是的,这看起来确实是一个非常好的保护 cookie 的方案。
该领域的另一个较新的方案是SCS:HTTP 的安全 Cookie 会话,这是一个可靠的方案,经过深思熟虑。我建议阅读该文档的安全讨论,以更好地了解可能存在的安全威胁。
为了帮助理解您提到的 cookie 方案的目的和作用,让我备份并提供一些上下文。Web 应用程序需要维护会话状态是很常见的:即,某些状态的生命周期仅限于当前会话,并且绑定到当前会话。有两种方法可以维护会话状态:
- 在服务器上存储会话状态。Web 服务器向浏览器提供一个会话 cookie:一个 cookie,其唯一目的是保存一个大的、不可猜测的位串,用作会话标识符。服务器保留一个查找表,每个打开的会话都有一个条目,该表从会话标识符映射到与该会话关联的所有会话状态。这使得 Web 应用程序代码可以轻松检索和更新与特定 HTTP/HTTPS 请求关联的会话状态。大多数 Web 应用程序框架都为在服务器端存储会话状态提供内置支持。
这是存储会话状态的最安全方式。因为会话状态存储在服务器上,客户端无法直接访问它。因此,攻击者无法读取或篡改会话状态(或重放旧值)。如果您的 Web 应用程序分布在多个后端计算节点上,则确实需要一些额外的工作来保持所有服务器之间的会话状态同步。
- 在客户端上存储会话状态。 另一种方法是将会话状态放入 cookie 并将 cookie 发送到浏览器。现在来自浏览器的每个后续请求都将包含会话状态。如果 Web 应用程序想要修改会话状态,它可以向浏览器发送更新的 cookie。
如果天真地完成,这是一个巨大的安全漏洞,因为它允许恶意客户端查看和修改会话状态。如果会话状态中包含任何机密数据,则前者是一个问题。如果服务器以任何方式信任或依赖会话状态,则后者是一个问题(例如,考虑会话状态是否包括登录用户的用户名,以及指示该用户是否为管理员的位;然后恶意客户端可以绕过 Web 应用程序的身份验证机制)。
您提到的提案和 SCS 计划旨在尽可能地防范这些风险。他们可以以最成功的方式做到这一点。但是,它们无法阻止恶意客户端删除 cookie(从而清除会话状态)。此外,如果旧版本来自同一会话,它们无法阻止恶意客户端重放 cookie 的旧值(从而将会话状态重置为旧值)。因此,Web 应用程序的开发人员需要了解这些风险,并注意会话状态中存储了哪些值。
因此,将会话状态存储在 cookie 中比将其存储在服务器上风险更大,即使您使用其中一种加密方案来保护 cookie。(但是,如果您要将会话状态存储在 cookie 中,我绝对建议您使用这两种方案之一来保护 cookie 中的值。)
为什么有人会在 cookie 中存储会话状态,因为它可以很容易地存储在服务器端?大多数时候,没有理由这样做。但是,在某些特殊情况下——例如 HTTP 服务器的存储量受到极大限制,或者在分布在多台机器上且对同步会话状态没有良好支持的负载平衡 Web 应用程序中——可能存在考虑将会话状态存储在 cookie 中的正当理由,然后使用其中一种方案是一个好主意。
PS 一个相关主题:如果您使用ASP.NET View State,请确保将其配置为加密和身份验证:即配置ViewStateEncryptionMode
为Always
和EnableViewStateMac
到true
;如果您使用多个服务器节点,请生成一个强加密密钥并配置每个服务器machineKey
以使用该密钥。最后,确保您拥有最新版本的 ASP.NET 框架;旧版本的 ViewState crypto存在严重的安全漏洞 。