I have an e-commerce app running on Rails 5.1.5 with redis-session-store
, but there seems to be a concurrency issue with the sessions when I open more than 1 tab at the same time.
Here's an example on how to reproduce the issue:
- Imagine you either have never accessed the app, or you just cleared the cookies;
- Then you open 2 links on other tabs pretty fast, so the second tab is open before the first one completes the request;
- Now in one of the tabs you have an invalid CSRF-token. And there's no way to tell which one it is.
From what I've seen so far, it seems the server does assign each request a different session_id, one overriding the other, as you can see in the reproduction below:
# 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
This session information is, of course, added to lograge payload like so:
#app/controllers/application_controller.rb
def append_info_to_payload(payload)
super
payload[:session] = request.session_options[:id] rescue ""
end
After that, one of the tabs will have an invalid csrf-token and that's going to cause really awkward problems, because since the Add to Cart buttons are all method: :post, remote: true
buttons, when users try to add a product to their carts, they'll actually wind up in an empty cart page due to rails invalidating the user session when a Can't verify CSRF token authenticity.
happens.
Any thoughts?
Edit:
By inspecting the Cookies in Chrome dev tools, I can tell that both tabs share the same session_id, as anyone would expect. So this problem is only related to the CSRF-token that's generated before the session_id gets overriden.