具有多个标签的会话并发问题导致无法验证CSRF令牌的真实性

时间:2019-06-05 15:30:56

标签: ruby-on-rails session concurrency redis csrf-token

我有一个使用redis-session-store在Rails 5.1.5上运行的电子商务应用程序,但是当我同时打开多个标签时,会话似乎存在并发问题。

以下是有关重现此问题的示例:

  • 想象您要么从未访问过该应用程序,要么只是清除了cookie;
  • 然后您很快打开了其他选项卡上的2个链接,因此在第一个选项卡完成请求之前打开了第二个选项卡;
  • 现在在其中一个标签中,您具有无效的CSRF令牌。而且没有办法知道它是哪一个。

从目前为止我所看到的,看来服务器确实为每个请求分配了一个不同的session_id,一个覆盖另一个请求,正如您在下面的复制图中看到的那样:

# first request
method=GET path=/my-url format=html controller=ProductsController action=show status=200 session=8cb3c8e8481f4e04772b5d77125132df

# second request
method=GET path=/other-url format=html controller=ProductsController action=show status=200 session=da126c627467fb5e2ab8be9e82c22b85

# notice the different session ids

当然,此会话信息将添加到日志有效负载中,如下所示:

#app/controllers/application_controller.rb

  def append_info_to_payload(payload)
    super
    payload[:session] = request.session_options[:id] rescue ""
  end

此后,其中一个选项卡将具有无效的csrf令牌,这将引起真正的尴尬问题,因为由于“添加到购物车”按钮都是method: :post, remote: true按钮,因此当用户尝试向其中添加产品时他们的购物车,实际上是由于Can't verify CSRF token authenticity.发生时导轨使用户会话无效,他们实际上会进入一个空的购物车页面。

有什么想法吗?

编辑:

通过检查Chrome开发人员工具中的Cookies,我可以知道两个标签共享了相同的session_id,正如任何人所期望的那样。 因此,此问题仅与覆盖session_id之前生成的CSRF令牌有关。

0 个答案:

没有答案