File rubygem-rack-CVE-2025-32441.patch of Package rubygem-rack.38666
Index: rack-2.0.8/lib/rack/session/pool.rb
===================================================================
--- rack-2.0.8.orig/lib/rack/session/pool.rb
+++ rack-2.0.8/lib/rack/session/pool.rb
@@ -53,6 +53,7 @@ module Rack
def write_session(req, session_id, new_session, options)
with_lock(req) do
+ return false unless get_session_with_fallback(session_id)
@pool.store session_id.private_id, new_session
session_id
end
@@ -62,7 +63,11 @@ module Rack
with_lock(req) do
@pool.delete(session_id.public_id)
@pool.delete(session_id.private_id)
- generate_sid unless options[:drop]
+ unless options[:drop]
+ sid = generate_sid
+ @pool.store(sid.private_id, {})
+ sid
+ end
end
end
Index: rack-2.0.8/test/spec_session_pool.rb
===================================================================
--- rack-2.0.8.orig/test/spec_session_pool.rb
+++ rack-2.0.8/test/spec_session_pool.rb
@@ -244,4 +244,52 @@ describe Rack::Session::Pool do
res = Rack::MockRequest.new(app).get("/")
res["Set-Cookie"].must_be_nil
end
+
+ user_id_session = Rack::Lint.new(lambda do |env|
+ session = env["rack.session"]
+
+ case env["PATH_INFO"]
+ when "/login"
+ session[:user_id] = 1
+ when "/logout"
+ if session[:user_id].nil?
+ raise "User not logged in"
+ end
+
+ session.delete(:user_id)
+ session.options[:renew] = true
+ when "/slow"
+ Fiber.yield
+ end
+
+ Rack::Response.new(session.inspect).to_a
+ end)
+
+ it "doesn't allow session id to be reused" do
+ app = Rack::Session::Pool.new(user_id_session)
+
+ login_response = Rack::MockRequest.new(app).get("/login")
+ login_cookie = login_response["Set-Cookie"]
+
+ slow_request = Fiber.new do
+ Rack::MockRequest.new(app).get("/slow", "HTTP_COOKIE" => login_cookie)
+ end
+ slow_request.resume
+
+ # Check that the session is valid:
+ response = Rack::MockRequest.new(app).get("/", "HTTP_COOKIE" => login_cookie)
+ response.body.must_equal({"user_id" => 1}.to_s)
+
+ logout_response = Rack::MockRequest.new(app).get("/logout", "HTTP_COOKIE" => login_cookie)
+ logout_cookie = logout_response["Set-Cookie"]
+
+ # Check that the session id is different after logout:
+ login_cookie[session_match].wont_equal logout_cookie[session_match]
+
+ slow_response = slow_request.resume
+
+ # Check that the cookie can't be reused:
+ response = Rack::MockRequest.new(app).get("/", "HTTP_COOKIE" => login_cookie)
+ response.body.must_equal "{}"
+ end
end