【问题标题】:Session Id placement: Form Hidden Field vs. HTTPOnly Cookie会话 ID 放置:表单隐藏字段与 HTTPOnly Cookie
【发布时间】:2016-09-11 14:58:01
【问题描述】:

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

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

【问题讨论】:

  • CSRF 和基于 cookie 的会话是一种“通用标准”。 Cookie 在某种程度上受到保护,可防止跨站点脚本,因为隐藏字段永远不会存在。
  • 哪些 XSS 攻击 cookie 可以处理隐藏字段会话无法处理的问题?
  • 那些不发送cookies的。
  • 改变主意了?有什么可以帮助您的吗?

标签: security session cookies xss csrf


【解决方案1】:

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

原因在于,这会固有地保护您免受CSRF 的侵害,因为对您的站点发出的任何跨域请求都意味着浏览器不会自动包含使 CSRF 攻击成为可能的会话标识符。它还中和了session fixation 攻击,因为没有 cookie 可毒化。此外,任何Login CSRF 也已死在水中。

要实现这一点,您需要通过 POST 方法对您网站上的每个操作(包括导航)进行操作。 GET 方法不合适,因为这会在浏览器历史记录、任何代理或服务器日志中默认暴露会话标识符,并且还可以通过 referer 标头泄漏。

例如,

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

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

</form>

请注意,这将阻止在用户重新提交表单的情况下使用后退按钮(如果操作不是safe 操作,这可能会很危险)。为了防止这种情况,您可以在处理完每个操作后刷新会话标识符。

另一个原因是这将保护您的网站免受攻击,例如POODLE。由于没有 cookie 可供中间人一次暴力破解一个字节,因此 POODLE 攻击将是徒劳的。

请注意,这种方法更难实现,并且没有多少网络框架默认支持它。

将CSRF-Tag放入表单隐藏字段和httpOnly cookie中的Session Id是否正确?

是的,这是大多数网站采用的方法。对于大多数用途而言,它“足够安全”——只有像网上银行这样的安全性非常高的系统才应该采用这种形式的方法。

【讨论】:

  • 谢谢。这很有帮助。我完全迷失在网上太多的会话管理方法中。
【解决方案2】:

我认为一个本质上并不比另一个安全。安全性通常是分层构建的。通过断言选择 A 可能比选择 B 更安全,当两个选择在同一垂直方向上发挥作用时,您就断言安全性止步于此。这在实践中是完全错误的和没有根据的。

通过主要以隐藏表单输入的形式传递会话 ID,您实际上会产生更多个问题,而不是您自己解决的问题。另外,我不同意这样的说法,即无论如何这都会使您受到 CSRF 的固有保护。

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

将 CSRF 令牌放置在隐藏输入中是正确的。通过 HTTP 标头将它们发送给客户端也不是不正确的。 CSRF 令牌本身不足以防止攻击。还需要服务器了解如何识别该令牌(据说是为该客户端唯一生成的)没有被同一用户重复使用,也没有绑定到另一个会话。

由于 CSRF 攻击通常基于您无法区分真实用户和恶意伪造的前提,其想法是通过为每个请求重新生成令牌来使伪造者的工作更加困难。再加上 use-only-once 要求,会话被劫持实际上不再重要。所以你真的不应该尝试在错误的级别解决这个问题,假设你可以通过在隐藏输入中传递会话 id 并说服自己这比将会话 id 存储在一个更安全的方式来解决这两个问题曲奇饼。 不是。应该有额外的安全层来保护您的会话免受会话劫持或会话固定攻击,例如使用SSL only cookiesHSTS,以及在重新验证请求时重新生成会话 ID(同时删除旧会话文件)。此外,强制对用户级非幂等操作进行重新身份验证。

但请不要假设隐藏的输入可以让您从本质上更安全地抵御 CSRF 或会话固定,或任何这些攻击。没有!

【讨论】:

  • 您在这里唯一关注的似乎是安全性,这很好。安全很重要。然而,你故意让程序员的工作更难,这只是意味着程序员可能会犯更多的错误,从而可能导致更糟糕的安全性。不要忘记,大多数成功的网络安全攻击往往会绕过最复杂和技术安全的系统,攻击容易出错的一件事(人类)。安全系统停止在程序员的错误。
  • 是的,我绝对不会将 CSRF 与 XSS 混淆。不知道你从我所说的任何事情中得出如此荒谬的结论。虽然请注意,我并不是建议您不能这样做。我要特别指出的是,您故意使编程变得更难,因为它们具有与替代方法所提供的完全相同的安全优势
  • 你只是从微观单一的角度来解决这个问题,这根本不实用。您认为普通开发人员在安全方面甚至遥不可及的假设是荒谬的。他们不是。否则,您将不会在整个网络上看到此类问题。您需要从开发人员会犯错误而不是如果的角度来解决问题。因为他们当他们这样做时,你绝对需要有多余的安全层来防范并采取行动作为针对开发人员的故障保险。
  • 我刚刚阅读了所有这些 cmets,但我仍然没有看到一个单一的论点,CSRF 如何使用隐藏的输入字段成为可能。会话仅存在于当前“窗口”内。单击“返回”、手动更改 url 或打开新选项卡将创建一个新的(可能为空的)会话,与旧会话无关。你会如何在这里做 CSRF?
  • @maple_shaft:默认情况下,网络并不安全——我同意这个解决方案“踩踏”了 RESTful 实现等,但它不是它的目的。它是关于制定一个可靠的解决方案,可以缓解 CSRF、会话固定、防止被劫持的会话、跟踪用户会话到他们正在查看的页面以及检测对定义序列之外的页面的访问。
猜你喜欢
  • 1970-01-01
  • 2010-09-07
  • 2012-11-14
  • 2017-02-04
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 2011-02-28
  • 2013-03-09
相关资源
最近更新 更多