Control: tags 1133007 + patch
Control: tags 1133007 + pending

Dear maintainer,

I've prepared an NMU for ruby-rack-session (versioned as 2.1.1-0.2) and 
uploaded it to DELAYED/7. Please feel free to tell me if I should cancel it.

cu
Adrian
diffstat for ruby-rack-session-2.1.1 ruby-rack-session-2.1.1

 changelog                                                               |    8 +
 patches/0001-Don-t-fall-back-to-unencrypted-coder-if-encryptors-a.patch |   66 ++++++++++
 patches/series                                                          |    1 
 3 files changed, 75 insertions(+)

diff -Nru ruby-rack-session-2.1.1/debian/changelog ruby-rack-session-2.1.1/debian/changelog
--- ruby-rack-session-2.1.1/debian/changelog	2025-07-15 14:10:44.000000000 +0300
+++ ruby-rack-session-2.1.1/debian/changelog	2026-05-02 11:37:55.000000000 +0300
@@ -1,3 +1,11 @@
+ruby-rack-session (2.1.1-0.2) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * CVE-2026-39324: decrypt failure falls back to accepting
+    unencrypted cookies (Closes: #1133007)
+
+ -- Adrian Bunk <[email protected]>  Sat, 02 May 2026 11:37:55 +0300
+
 ruby-rack-session (2.1.1-0.1) unstable; urgency=medium
 
   * Non-maintainer upload.
diff -Nru ruby-rack-session-2.1.1/debian/patches/0001-Don-t-fall-back-to-unencrypted-coder-if-encryptors-a.patch ruby-rack-session-2.1.1/debian/patches/0001-Don-t-fall-back-to-unencrypted-coder-if-encryptors-a.patch
--- ruby-rack-session-2.1.1/debian/patches/0001-Don-t-fall-back-to-unencrypted-coder-if-encryptors-a.patch	1970-01-01 02:00:00.000000000 +0200
+++ ruby-rack-session-2.1.1/debian/patches/0001-Don-t-fall-back-to-unencrypted-coder-if-encryptors-a.patch	2026-05-02 11:37:44.000000000 +0300
@@ -0,0 +1,66 @@
+From aa37be73b5126bc4aed4069554204f3a6816e16c Mon Sep 17 00:00:00 2001
+From: Samuel Williams <[email protected]>
+Date: Mon, 6 Apr 2026 11:37:15 +1200
+Subject: Don't fall back to unencrypted coder if encryptors are present.
+
+---
+ lib/rack/session/cookie.rb  |  6 ++++--
+ test/spec_session_cookie.rb | 25 +++++++++++++++++++++++++
+ 2 files changed, 29 insertions(+), 2 deletions(-)
+
+diff --git a/lib/rack/session/cookie.rb b/lib/rack/session/cookie.rb
+index 830a4e3..c7dabd1 100644
+--- a/lib/rack/session/cookie.rb
++++ b/lib/rack/session/cookie.rb
+@@ -237,8 +237,10 @@ module Rack
+               # Decode using legacy HMAC decoder
+               session_data = @legacy_hmac_coder.decode(session_data)
+ 
+-            elsif !session_data && coder
+-              # Use the coder option, which has the potential to be very unsafe
++            elsif !session_data && encryptors.empty? && coder
++              # Use the coder option, which has the potential to be very unsafe.
++              # This path is only reached when no encryptors (secrets:) are configured;
++              # if encryptors are present but decryption failed, the cookie is rejected.
+               session_data = coder.decode(cookie_data)
+             end
+           end
+diff --git a/test/spec_session_cookie.rb b/test/spec_session_cookie.rb
+index bb2c551..fc03d1f 100644
+--- a/test/spec_session_cookie.rb
++++ b/test/spec_session_cookie.rb
+@@ -365,6 +365,31 @@ describe Rack::Session::Cookie do
+     response.body.must_equal ({"counter"=>1}.to_s)
+   end
+ 
++  it 'rejects a forged plain Base64::Marshal cookie when secrets: is configured' do
++    # Construct a forged cookie without knowing the secret: plain Base64-encoded
++    # Marshal payload, identical to what an attacker would send.
++    forged_payload = { 'session_id' => 'attacker-fixed', 'counter' => 999 }
++    forged_cookie = "rack.session=#{Base64.strict_encode64(Marshal.dump(forged_payload))}"
++
++    app = [incrementor, { secrets: @secret }]
++
++    # The forged cookie must be rejected; session starts fresh (counter = 1).
++    response = response_for(app: app, cookie: forged_cookie)
++    response.body.must_equal ({"counter" => 1}.to_s)
++  end
++
++  it 'rejects a forged plain Base64::Marshal cookie when secrets: and serialize_json: true are configured' do
++    # serialize_json: true only affects the encryptor serializer; the coder
++    # fallback must also be suppressed when encryptors are configured.
++    forged_payload = { 'session_id' => 'attacker-fixed', 'counter' => 999 }
++    forged_cookie = "rack.session=#{Base64.strict_encode64(Marshal.dump(forged_payload))}"
++
++    app = [incrementor, { secrets: @secret, serialize_json: true }]
++
++    response = response_for(app: app, cookie: forged_cookie)
++    response.body.must_equal ({"counter" => 1}.to_s)
++  end
++
+   it 'rejects session cookie with different purpose' do
+     app = [incrementor, { secrets: @secrets }]
+     other_app = [incrementor, { secrets: @secrets, key: 'other' }]
+-- 
+2.47.3
+
diff -Nru ruby-rack-session-2.1.1/debian/patches/series ruby-rack-session-2.1.1/debian/patches/series
--- ruby-rack-session-2.1.1/debian/patches/series	2025-03-08 17:10:05.000000000 +0200
+++ ruby-rack-session-2.1.1/debian/patches/series	2026-05-02 11:37:55.000000000 +0300
@@ -1 +1,2 @@
 avoid-relative-require-to-lib.patch
+0001-Don-t-fall-back-to-unencrypted-coder-if-encryptors-a.patch
_______________________________________________
Pkg-ruby-extras-maintainers mailing list
[email protected]
https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/pkg-ruby-extras-maintainers

Reply via email to