SECURITY: Ensure _forum_session cookies cannot be reused between sites (#14950)

SECURITY: Ensure _forum_session cookies cannot be reused between sites (#14950)

This only affects multisite Discourse instances (where multiple forums are served from a single application server). The vast majority of self-hosted Discourse forums do not fall into this category.

On affected instances, this vulnerability could allow encrypted session cookies to be re-used between sites served by the same application instance.

diff --git a/Gemfile.lock b/Gemfile.lock
index bedceee..6cbb820 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -323,7 +323,7 @@ GEM
       activerecord (~> 6.0)
       concurrent-ruby
       railties (~> 6.0)
-    rails_multisite (3.1.0)
+    rails_multisite (4.0.0)
       activerecord (> 5.0, < 7)
       railties (> 5.0, < 7)
     railties (6.1.4.1)
diff --git a/spec/integration/multisite_cookies_spec.rb b/spec/integration/multisite_cookies_spec.rb
new file mode 100644
index 0000000..6256eef
--- /dev/null
+++ b/spec/integration/multisite_cookies_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe 'multisite', type: [:multisite, :request] do
+  it "works" do
+    get "http://test.localhost/session/csrf.json"
+    expect(response.status).to eq(200)
+    cookie = response.cookies["_forum_session"]
+    id1 = session["session_id"]
+
+    get "http://test.localhost/session/csrf.json", headers: { "Cookie" => "_forum_session=#{cookie};" }
+    expect(response.status).to eq(200)
+    id2 = session["session_id"]
+
+    expect(id1).to eq(id2)
+
+    get "http://test2.localhost/session/csrf.json", headers: { "Cookie" => "_forum_session=#{cookie};" }
+    expect(response.status).to eq(200)
+    id3 = session["session_id"]
+
+    # Session cookie was rejected and rotated
+    expect(id2).not_to eq(id3)
+  end
+end

GitHub sha: f45853676f9e061ce8f949405969bc7b1ac651fe

This commit appears in #14950 which was approved by danielwaterworth. It was merged by davidtaylorhq.