会话 ID 放置:表单隐藏字段与 HTTPOnly Cookie

Session Id placement: Form Hidden Field vs. HTTPOnly Cookie

与 cookie 相比,将会话 ID 置于隐藏表单输入中有哪些优点和缺点?

将 CSRF-Tag 放在隐藏的表单输入字段中并将会话 ID 放在 httpOnly cookie 中是否正确?哪个更安全?

如果将 Session ID 放在隐藏的表单字段中,这样会更安全,但会影响用户体验。

原因是,这会本质上保护你免受 CSRF because any cross-domain requests made to your site will mean that the browser will not automatically include the session identifier that makes CSRF attacks possible. It also neutralises session fixation attacks as there is no cookie to poison. Additionally any Login CSRF 也死在水里。

要实现这一点,您需要通过 POST 方法对站点上的所有操作(包括导航)进行操作。 GET 方法不合适,因为这会在浏览器历史记录、默认情况下在任何代理或服务器日志中公开 session 标识符,并且还可能通过 referer header.

例如,

<form method="post" action="/executeAction">

  <input type="hidden" name="sessionId" value="12345678901234567890" />
  <input type="hidden" name="action" value="navigateToAccountStatus" />

</form>

请注意,这将阻止用户在没有 re-submitting 表单的情况下使用后退按钮(如果操作不是 safe 操作,这可能很危险)。为防止这种情况,您可以在处理每个操作后刷新 session 标识符。

另一个原因是这将保护您的网站免受 POODLE 等攻击。由于没有用于 Man-In-The-Middle 一次暴力破解一个字节的 cookie,因此 POODLE 攻击将是徒劳的。

请注意,这种方法更难实施,并且没有多少人 web-frameworks 默认支持它。

Is it correct to put CSRF-Tag in form hidden field and Session Id in httpOnly cookie?

是的,这是大多数网站采用的方法。对于大多数用途而言,它“足够安全”——只有非常高安全性的系统(如网上银行)才应采用表单方法。

我不认为一个本质上不如另一个安全。安全性通常是分层构建的。通过断言选项 A 可以 选项 B 更安全,当两个选项在同一垂直方向上播放时,您断言安全性就此止步。这完全是错误的,在实践中没有得到证实。

通过主要以隐藏表单输入的形式传递 session ID,您实际上创造了 比您自己解决的问题更多。另外,我不同意这样的说法,即这无论如何都会让你在本质上受到 CSRF 的保护。

当您考虑 session 服务的目的时(通过其他无状态协议在服务器和客户端之间保留状态),说我将传递所有 session ids 通过隐藏的输入字段。因为,一方面,并​​非对您的服务器发出的每个请求都涉及使用表单。另一方面,当用户刷新页面或关闭浏览器时,状态就会丢失。这一点都不实用。

将 CSRF 令牌放置在隐藏输入中是正确的。通过 HTTP headers 将它们一起发送到客户端也没有错。 CSRF 令牌本身不足以阻止攻击。还需要的是,服务器了解如何识别这个据称是为此客户端唯一生成的令牌没有被重复使用,也没有被同一用户绑定到另一个 session。

由于通常 CSRF 攻击的前提是您无法区分真实用户和恶意伪造者,因此想法是通过为每个请求重新生成令牌来增加伪造者的工作难度。再加上 use-only-once 要求,session 被劫持实际上不再重要了。所以你真的不应该尝试在错误的层面上解决这个问题,假设你可以通过在隐藏输入中传递你的 session id 并说服自己这比存储更安全来解决这两个问题session cookie 中的 ID。 不是。应该有额外的安全层来保护您的 session 免受 session 劫持或 session 固定攻击,例如使用 SSL only cookies, HSTS 和重新生成 session id(同时删除旧 session 文件)根据 re-authentication 请求。此外,强制 re-authentication 进行 user-level non-idempotent 操作。

但是请不要假设隐藏的输入会让您在本质上更安全,免受 CSRF 或 Session 固定,或任何这些攻击。它没有!