[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#972310: buster-pu: package puma/3.12.0-2+deb10u2



Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@packages.debian.org
Usertags: pu

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

There are several security advisories open for the puma version in Buster:

  CVE-2020-5247
  CVE-2020-5249
  CVE-2020-11076
  CVE-2020-11077

This upload fixes all these issues with patches taken from upstream's git
repository. The added patches contain references to the commits used.
Furthermore the upload contains a two-liner to add patch headers to an
existing patch.

A few new tests from upstream are added as well and a few other have been
ifixed to apply to the fixed sources. Non-necessary changes have been omitted.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in stable
  [pending] the issue is verified as fixed in unstable

Unstable contains the 4.x series of puma while buster contains the 3.12 series.
The upload of puma 4.3.6 will follow within one or two days of this report.

Please don't hesitate to contact me if any questions arise.

Regards, Daniel

- -- System Information:
Debian Release: bullseye/sid
  APT prefers unstable
  APT policy: (990, 'unstable'), (500, 'testing'), (500, 'stable'), (1, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 5.8.0-3-amd64 (SMP w/8 CPU threads)
Kernel taint flags: TAINT_OOT_MODULE
Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEvu1N7VVEpMA+KD3HS80FZ8KW0F0FAl+I6K0ACgkQS80FZ8KW
0F1jSg//XplFcjLWUESWhyT6UWng0bRxafeQvBen5rhi35WCpQdkkGR5VVH7WiEQ
cPLXjVifn66vJtP7/BKpqIWKJkZnotdNRtNXPslYkRb6WvQqTPUguPKQUM7fxOw3
qkKJN0bY49lPnWObiw+CFcXlZQ+lwwbKh7/Ud4MBNoHDd5nWRLwFzs2QndARR2u0
i7nv31ihaD85evcSX6MWKtqXLUzGY4dtp7RR0ecyzcQmyxwT8GEcNxqWBzzVqisk
CkRwvHZESGM+eqcTiqIRFmvMEj+0H4foo5SxGPq/WKlH0/ENvt2VwnDKswyavc5q
YuC1ZUB+hI5uJLJtQ3/ES3FrNgPdH9hjFutG3qzBWi1+M76rrSpT281dr0DYe33R
ycDk2+PDbGpAg13j819MXWSDfR91nYDZ0TOWq1Kx+s2xQ5ObIw/KtvX/K93Vjwb4
SyPrYvqLoeZyAm+erNjyx+BhkrNnzQmkCVgNAD/9N9tHmN1DIOpH4CNNc1zCQfWK
vXmK8ZLuKxGQWNmOMy0JHnDxlHNy1XDvJ8tJOdmjHg6ylncueepFhwQu5nUDv8rs
eW+ICHejvc/W/tBO9TOyB2AE6yMLafAyzMH9qHn/mZPkcR0+s1F3Pu1A96fnz2vn
hMDVrBeoLOD/UUuLe6yR5Reehewmfk3HxoTIFKipB9T+imiTLbw=
=llit
-----END PGP SIGNATURE-----
diff -Nru puma-3.12.0/debian/changelog puma-3.12.0/debian/changelog
--- puma-3.12.0/debian/changelog	2020-03-04 00:15:43.000000000 +0100
+++ puma-3.12.0/debian/changelog	2020-10-15 23:39:36.000000000 +0200
@@ -1,3 +1,23 @@
+puma (3.12.0-2+deb10u2) buster; urgency=medium
+
+  * Team upload.
+  * d/patches/0009-disable-tests-failing-in-single-cpu.patch: Add author and
+    bug tracker information.
+  * d/patches/CVE-2020-5247.patch: Add patch to fix CVE-2020-5247.
+    - Fix header value could inject their own HTTP response (closes: #952766).
+  * d/patches/CVE-2020-5249.patch: Add patch to fix CVE-2020-5249.
+    - Fix splitting newlines in headers and another vector for HTTP injection
+      (closes: #953122).
+  * d/patches/CVE-2020-11076.patch: Add patch to fix CVE-2020-11076.
+    - Better handle client input to fix HTTP Smuggling via Transfer-Encoding
+      header (closes: #972102).
+  * d/patches/CVE-2020-11077.patch: Add patch to fix CVE-2020-11077.
+    - Reduce ambiguity of headers to fix HTTP Smuggling via Transfer-Encoding
+      header (closes: #972102).
+  * d/patches/series: Enable new patches.
+
+ -- Daniel Leidert <dleidert@debian.org>  Thu, 15 Oct 2020 23:39:36 +0200
+
 puma (3.12.0-2+deb10u1) buster; urgency=medium
 
   * Team upload.
diff -Nru puma-3.12.0/debian/patches/0009-disable-tests-failing-in-single-cpu.patch puma-3.12.0/debian/patches/0009-disable-tests-failing-in-single-cpu.patch
--- puma-3.12.0/debian/patches/0009-disable-tests-failing-in-single-cpu.patch	2020-03-04 00:15:43.000000000 +0100
+++ puma-3.12.0/debian/patches/0009-disable-tests-failing-in-single-cpu.patch	2020-10-15 23:39:36.000000000 +0200
@@ -1,9 +1,19 @@
+From: Pirate Praveen <praveen@debian.org>
+Date: Sun, 10 Feb 2019 18:56:23 +0530
+Subject: disable-tests-failing-in-single-cpu
+
 Disable test failing on single cpu
-https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=921931
 
+Bug-Debian: https://bugs.debian.org/921931
+---
+ test/test_pumactl.rb | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/test/test_pumactl.rb b/test/test_pumactl.rb
+index 813ec32..11466b2 100644
 --- a/test/test_pumactl.rb
 +++ b/test/test_pumactl.rb
-@@ -33,7 +33,7 @@
+@@ -33,7 +33,7 @@ class TestPumaControlCli < Minitest::Test
  
    def test_control_url
      skip if Puma.jruby? || Puma.windows?
diff -Nru puma-3.12.0/debian/patches/CVE-2020-11076.patch puma-3.12.0/debian/patches/CVE-2020-11076.patch
--- puma-3.12.0/debian/patches/CVE-2020-11076.patch	1970-01-01 01:00:00.000000000 +0100
+++ puma-3.12.0/debian/patches/CVE-2020-11076.patch	2020-10-15 23:39:36.000000000 +0200
@@ -0,0 +1,37 @@
+From: Evan Phoenix <evan@phx.io>
+Date: Mon, 18 May 2020 14:43:00 -0700
+Subject: [PATCH] Better handle client input
+
+Acked-By: Daniel Leidert <dleidert@debian.org>
+Applied-Upstream: 3.12.5
+Bug: https://github.com/puma/puma/security/advisories/GHSA-x7jg-6pwg-fx5h
+Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2020-11076
+Bug-Debian: https://bugs.debian.org/972102
+Origin: https://github.com/puma/puma/commit/87e7fe46fdadd9ccc83fdd41d33a25b931a1644b.patch
+---
+ lib/puma/client.rb | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/lib/puma/client.rb b/lib/puma/client.rb
+index c395555..9a9b14d 100644
+--- a/lib/puma/client.rb
++++ b/lib/puma/client.rb
+@@ -241,8 +241,16 @@ module Puma
+ 
+       te = @env[TRANSFER_ENCODING2]
+ 
+-      if te && CHUNKED.casecmp(te) == 0
+-        return setup_chunked_body(body)
++      if te
++        if te.include?(",")
++          te.split(",").each do |part|
++            if CHUNKED.casecmp(part.strip) == 0
++              return setup_chunked_body(body)
++            end
++          end
++        elsif CHUNKED.casecmp(te) == 0
++          return setup_chunked_body(body)
++        end
+       end
+ 
+       @chunked_body = false
diff -Nru puma-3.12.0/debian/patches/CVE-2020-11077.patch puma-3.12.0/debian/patches/CVE-2020-11077.patch
--- puma-3.12.0/debian/patches/CVE-2020-11077.patch	1970-01-01 01:00:00.000000000 +0100
+++ puma-3.12.0/debian/patches/CVE-2020-11077.patch	2020-10-15 23:39:36.000000000 +0200
@@ -0,0 +1,123 @@
+From: Evan Phoenix <evan@phx.io>
+Date: Tue, 19 May 2020 15:20:10 -0700
+Subject: [PATCH] Reduce ambiguity of headers
+
+The patch also requires to fix a test not handled in upstream's patch:
+https://github.com/puma/puma/commit/0a3c09a0603857f088571d0eb69e0b9adee0fed1
+
+Acked-By: Daniel Leidert <dleidert@debian.org>
+Applied-Upstream: 3.12.6
+Bug: https://github.com/puma/puma/security/advisories/GHSA-w64w-qqph-5gxm
+Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2020-11077
+Bug-Debian: https://bugs.debian.org/972102
+Origin: https://github.com/puma/puma/compare/3.12.5...v3.12.6.patch
+---
+ ext/puma_http11/http11_parser.c  |  4 +++-
+ ext/puma_http11/http11_parser.rl |  4 +++-
+ lib/puma/server.rb               | 31 +++++++++++++++++++++++++++++++
+ test/test_puma_server.rb         |  3 ++-
+ 4 files changed, 39 insertions(+), 3 deletions(-)
+
+diff --git a/ext/puma_http11/http11_parser.c b/ext/puma_http11/http11_parser.c
+index 453f8cd..e8844a3 100644
+--- a/ext/puma_http11/http11_parser.c
++++ b/ext/puma_http11/http11_parser.c
+@@ -14,12 +14,14 @@
+ 
+ /*
+  * capitalizes all lower-case ASCII characters,
+- * converts dashes to underscores.
++ * converts dashes to underscores, and underscores to commas.
+  */
+ static void snake_upcase_char(char *c)
+ {
+     if (*c >= 'a' && *c <= 'z')
+       *c &= ~0x20;
++    else if (*c == '_')
++      *c = ',';
+     else if (*c == '-')
+       *c = '_';
+ }
+diff --git a/ext/puma_http11/http11_parser.rl b/ext/puma_http11/http11_parser.rl
+index 880c1d4..62452ba 100644
+--- a/ext/puma_http11/http11_parser.rl
++++ b/ext/puma_http11/http11_parser.rl
+@@ -12,12 +12,14 @@
+ 
+ /*
+  * capitalizes all lower-case ASCII characters,
+- * converts dashes to underscores.
++ * converts dashes to underscores, and underscores to commas.
+  */
+ static void snake_upcase_char(char *c)
+ {
+     if (*c >= 'a' && *c <= 'z')
+       *c &= ~0x20;
++    else if (*c == '_')
++      *c = ',';
+     else if (*c == '-')
+       *c = '_';
+ }
+diff --git a/lib/puma/server.rb b/lib/puma/server.rb
+index 886c965..89d8632 100644
+--- a/lib/puma/server.rb
++++ b/lib/puma/server.rb
+@@ -663,6 +663,37 @@ module Puma
+         }
+       end
+ 
++      # Fixup any headers with , in the name to have _ now. We emit
++      # headers with , in them during the parse phase to avoid ambiguity
++      # with the - to _ conversion for critical headers. But here for
++      # compatibility, we'll convert them back. This code is written to
++      # avoid allocation in the common case (ie there are no headers
++      # with , in their names), that's why it has the extra conditionals.
++
++      to_delete = nil
++      to_add = nil
++
++      env.each do |k,v|
++        if k.start_with?("HTTP_") and k.include?(",") and k != "HTTP_TRANSFER,ENCODING"
++          if to_delete
++            to_delete << k
++          else
++            to_delete = [k]
++          end
++
++          unless to_add
++            to_add = {}
++          end
++
++          to_add[k.gsub(",", "_")] = v
++        end
++      end
++
++      if to_delete
++        to_delete.each { |k| env.delete(k) }
++        env.merge! to_add
++      end
++
+       # A rack extension. If the app writes #call'ables to this
+       # array, we will invoke them when the request is done.
+       #
+diff --git a/test/test_puma_server.rb b/test/test_puma_server.rb
+index 079c42c..4c375c9 100644
+--- a/test/test_puma_server.rb
++++ b/test/test_puma_server.rb
+@@ -118,7 +118,7 @@ class TestPumaServer < Minitest::Test
+ 
+     req = Net::HTTP::Get.new("/")
+     req['HOST'] = "example.com"
+-    req['X_FORWARDED_PROTO'] = "https"
++    req['X-FORWARDED-PROTO'] = "https"
+ 
+     res = Net::HTTP.start @host, @server.connected_port do |http|
+       http.request(req)
+@@ -137,6 +137,7 @@ class TestPumaServer < Minitest::Test
+ 
+     req = Net::HTTP::Get.new("/")
+     req['HOST'] = "example.com"
++    req['X-FORWARDED-PROTO'] = "https,http"
+ 
+     res = Net::HTTP.start @host, @server.connected_port do |http|
+       http.request(req)
diff -Nru puma-3.12.0/debian/patches/CVE-2020-5247.patch puma-3.12.0/debian/patches/CVE-2020-5247.patch
--- puma-3.12.0/debian/patches/CVE-2020-5247.patch	1970-01-01 01:00:00.000000000 +0100
+++ puma-3.12.0/debian/patches/CVE-2020-5247.patch	2020-10-15 23:39:36.000000000 +0200
@@ -0,0 +1,72 @@
+From: Nate Berkopec <nate.berkopec@gmail.com>
+Date: Thu, 27 Feb 2020 11:52:27 -0600
+Subject: [PATCH] Merge pull request from GHSA-84j7-475p-hp8v
+
+header value could inject a CR or LF and inject their own HTTP response.
+(actually the patch to fix CVE-CVE-2020-5249 superseedes these changes)
+
+Acked-By: Daniel Leidert <dleidert@debian.org>
+Applied-Upstream: 3.12.3
+Bug: https://github.com/puma/puma/security/advisories/GHSA-84j7-475p-hp8v
+Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2020-5247
+Bug-Debian: https://bugs.debian.org/952766
+Origin: https://github.com/puma/puma/commit/1b17e85a06183cd169b41ca719928c26d44a6e03.patch
+---
+ lib/puma/const.rb        |  1 +
+ lib/puma/server.rb       |  2 ++
+ test/test_puma_server.rb | 19 +++++++++++++++++++
+ 3 files changed, 22 insertions(+)
+
+diff --git a/lib/puma/const.rb b/lib/puma/const.rb
+index 7fc105c..a06d866 100644
+--- a/lib/puma/const.rb
++++ b/lib/puma/const.rb
+@@ -226,6 +226,7 @@ module Puma
+     COLON = ": ".freeze
+ 
+     NEWLINE = "\n".freeze
++    CRLF_REGEX = /[\r\n]/.freeze
+ 
+     HIJACK_P = "rack.hijack?".freeze
+     HIJACK = "rack.hijack".freeze
+diff --git a/lib/puma/server.rb b/lib/puma/server.rb
+index 66a982a..3ee5fcc 100644
+--- a/lib/puma/server.rb
++++ b/lib/puma/server.rb
+@@ -672,6 +672,8 @@ module Puma
+           status, headers, res_body = @app.call(env)
+ 
+           return :async if req.hijacked
++          # Checking to see if an attacker is trying to inject headers into the response
++          headers.reject! { |_k, v| CRLF_REGEX =~ v.to_s }
+ 
+           status = status.to_i
+ 
+diff --git a/test/test_puma_server.rb b/test/test_puma_server.rb
+index 2536f0a..0649cbc 100644
+--- a/test/test_puma_server.rb
++++ b/test/test_puma_server.rb
+@@ -691,4 +691,23 @@ EOF
+ 
+     assert_equal "HTTP/1.0 200 OK\r\nX-Empty-Header: \r\n\r\n", data
+   end
++
++  # https://github.com/ruby/ruby/commit/d9d4a28f1cdd05a0e8dabb36d747d40bbcc30f16
++  def test_prevent_response_splitting_headers
++    server_run app: ->(_) { [200, {'X-header' => "malicious\r\nCookie: hack"}, ["Hello"]] }
++    data = send_http_and_read "HEAD / HTTP/1.0\r\n\r\n"
++    refute_match 'hack', data
++  end
++
++  def test_prevent_response_splitting_headers_cr
++    server_run app: ->(_) { [200, {'X-header' => "malicious\rCookie: hack"}, ["Hello"]] }
++    data = send_http_and_read "HEAD / HTTP/1.0\r\n\r\n"
++    refute_match 'hack', data
++  end
++
++  def test_prevent_response_splitting_headers_lf
++    server_run app: ->(_) { [200, {'X-header' => "malicious\nCookie: hack"}, ["Hello"]] }
++    data = send_http_and_read "HEAD / HTTP/1.0\r\n\r\n"
++    refute_match 'hack', data
++  end
+ end
diff -Nru puma-3.12.0/debian/patches/CVE-2020-5249.patch puma-3.12.0/debian/patches/CVE-2020-5249.patch
--- puma-3.12.0/debian/patches/CVE-2020-5249.patch	1970-01-01 01:00:00.000000000 +0100
+++ puma-3.12.0/debian/patches/CVE-2020-5249.patch	2020-10-15 23:39:36.000000000 +0200
@@ -0,0 +1,189 @@
+From: Nate Berkopec <nate.berkopec@gmail.com>
+Date: Fri, 28 Feb 2020 12:53:29 -0600
+Subject: [PATCH] HTTP Injection - fix bug + 1 more vector (#2136)
+
++ Fixes a problem in 4.3.2/3.12.3 where we were not splitting newlines in headers according to Rack spec
++ Fixes another vector for HTTP injection - early hints
+
+Acked-By: Daniel Leidert <dleidert@debian.org>
+Applied-Upstream: 3.12.4
+Bug: https://github.com/puma/puma/security/advisories/GHSA-33vf-4xgg-9r58
+Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2020-5249
+Bug-Debian: https://bugs.debian.org/953122
+Origin: https://github.com/puma/puma/commit/e79a5b28f618fa04b7060c87f0da34d299462416.patch
+Origin: https://github.com/puma/puma/commit/f809e6b7aa3083afb8da5eb54bdd45fc391d1ba1.patch
+Origin: https://github.com/puma/puma/commit/3a2b9186b7ca31c9cfda8c88b824618e9c3d842c.patch
+---
+ lib/puma/const.rb        |  2 +-
+ lib/puma/server.rb       | 10 +++++--
+ test/test_puma_server.rb | 76 +++++++++++++++++++++++++++++++++++++++++-------
+ 3 files changed, 75 insertions(+), 13 deletions(-)
+
+diff --git a/lib/puma/const.rb b/lib/puma/const.rb
+index a06d866..c8a8d3f 100644
+--- a/lib/puma/const.rb
++++ b/lib/puma/const.rb
+@@ -226,7 +226,7 @@ module Puma
+     COLON = ": ".freeze
+ 
+     NEWLINE = "\n".freeze
+-    CRLF_REGEX = /[\r\n]/.freeze
++    HTTP_INJECTION_REGEX = /[\r\n]/.freeze
+ 
+     HIJACK_P = "rack.hijack?".freeze
+     HIJACK = "rack.hijack".freeze
+diff --git a/lib/puma/server.rb b/lib/puma/server.rb
+index 3ee5fcc..886c965 100644
+--- a/lib/puma/server.rb
++++ b/lib/puma/server.rb
+@@ -651,6 +651,7 @@ module Puma
+           headers.each_pair do |k, vs|
+             if vs.respond_to?(:to_s) && !vs.to_s.empty?
+               vs.to_s.split(NEWLINE).each do |v|
++                next if possible_header_injection?(v)
+                 fast_write client, "#{k}: #{v}\r\n"
+               end
+             else
+@@ -672,8 +673,6 @@ module Puma
+           status, headers, res_body = @app.call(env)
+ 
+           return :async if req.hijacked
+-          # Checking to see if an attacker is trying to inject headers into the response
+-          headers.reject! { |_k, v| CRLF_REGEX =~ v.to_s }
+ 
+           status = status.to_i
+ 
+@@ -751,6 +750,7 @@ module Puma
+         headers.each do |k, vs|
+           case k.downcase
+           when CONTENT_LENGTH2
++            next if possible_header_injection?(vs)
+             content_length = vs
+             next
+           when TRANSFER_ENCODING
+@@ -763,6 +763,7 @@ module Puma
+ 
+           if vs.respond_to?(:to_s) && !vs.to_s.empty?
+             vs.to_s.split(NEWLINE).each do |v|
++              next if possible_header_injection?(v)
+               lines.append k, colon, v, line_ending
+             end
+           else
+@@ -1029,5 +1030,10 @@ module Puma
+     def shutting_down?
+       @status == :stop || @status == :restart
+     end
++
++    def possible_header_injection?(header_value)
++      HTTP_INJECTION_REGEX =~ header_value.to_s
++    end
++    private :possible_header_injection?
+   end
+ end
+diff --git a/test/test_puma_server.rb b/test/test_puma_server.rb
+index 0649cbc..079c42c 100644
+--- a/test/test_puma_server.rb
++++ b/test/test_puma_server.rb
+@@ -16,6 +16,13 @@ class TestPumaServer < Minitest::Test
+     @server.stop(true)
+   end
+ 
++  def server_run(app: @app, early_hints: false)
++    @server.app = app
++    @server.add_tcp_listener @host, @port
++    @server.early_hints = true if early_hints
++    @server.run
++  end
++
+   def header(sock)
+     header = []
+     while true
+@@ -27,6 +34,13 @@ class TestPumaServer < Minitest::Test
+     header
+   end
+ 
++  def send_http_and_read(req)
++    port = @server.connected_port
++    sock = TCPSocket.new @host, port
++    sock << req
++    sock.read
++  end
++
+   def test_proper_stringio_body
+     data = nil
+ 
+@@ -692,22 +706,64 @@ EOF
+     assert_equal "HTTP/1.0 200 OK\r\nX-Empty-Header: \r\n\r\n", data
+   end
+ 
+-  # https://github.com/ruby/ruby/commit/d9d4a28f1cdd05a0e8dabb36d747d40bbcc30f16
+-  def test_prevent_response_splitting_headers
+-    server_run app: ->(_) { [200, {'X-header' => "malicious\r\nCookie: hack"}, ["Hello"]] }
++  # Rack may pass a newline in a header expecting us to split it.
++  def test_newline_splits
++    server_run app: ->(_) { [200, {'X-header' => "first line\nsecond line"}, ["Hello"]] }
+     data = send_http_and_read "HEAD / HTTP/1.0\r\n\r\n"
+-    refute_match 'hack', data
++
++    assert_match "X-header: first line\r\nX-header: second line\r\n", data
+   end
+ 
+-  def test_prevent_response_splitting_headers_cr
+-    server_run app: ->(_) { [200, {'X-header' => "malicious\rCookie: hack"}, ["Hello"]] }
++  def test_newline_splits_in_early_hint
++    server_run early_hints: true, app: ->(env) do
++      env['rack.early_hints'].call({'X-header' => "first line\nsecond line"})
++      [200, {}, ["Hello world!"]]
++    end
+     data = send_http_and_read "HEAD / HTTP/1.0\r\n\r\n"
+-    refute_match 'hack', data
++
++    assert_match "X-header: first line\r\nX-header: second line\r\n", data
+   end
+ 
+-  def test_prevent_response_splitting_headers_lf
+-    server_run app: ->(_) { [200, {'X-header' => "malicious\nCookie: hack"}, ["Hello"]] }
++  # To comply with the Rack spec, we have to split header field values
++  # containing newlines into multiple headers.
++  def assert_does_not_allow_http_injection(app, opts = {})
++    server_run(early_hints: opts[:early_hints], app: app)
+     data = send_http_and_read "HEAD / HTTP/1.0\r\n\r\n"
+-    refute_match 'hack', data
++
++    refute_match(/[\r\n]Cookie: hack[\r\n]/, data)
++  end
++
++  # HTTP Injection Tests
++  #
++  # Puma should prevent injection of CR and LF characters into headers, either as
++  # CRLF or CR or LF, because browsers may interpret it at as a line end and
++  # allow untrusted input in the header to split the header or start the
++  # response body. While it's not documented anywhere and they shouldn't be doing
++  # it, Chrome and curl recognize a lone CR as a line end. According to RFC,
++  # clients SHOULD interpret LF as a line end for robustness, and CRLF is the
++  # specced line end.
++  #
++  # There are three different tests because there are three ways to set header
++  # content in Puma. Regular (rack env), early hints, and a special case for
++  # overriding content-length.
++  {"cr" => "\r", "lf" => "\n", "crlf" => "\r\n"}.each do |suffix, line_ending|
++    # The cr-only case for the following test was CVE-2020-5247
++    define_method("test_prevent_response_splitting_headers_#{suffix}") do
++      app = ->(_) { [200, {'X-header' => "untrusted input#{line_ending}Cookie: hack"}, ["Hello"]] }
++      assert_does_not_allow_http_injection(app)
++    end
++
++    define_method("test_prevent_response_splitting_headers_early_hint_#{suffix}") do
++      app = ->(env) do
++        env['rack.early_hints'].call("X-header" => "untrusted input#{line_ending}Cookie: hack")
++        [200, {}, ["Hello"]]
++      end
++      assert_does_not_allow_http_injection(app, early_hints: true)
++    end
++
++    define_method("test_prevent_content_length_injection_#{suffix}") do
++      app = ->(_) { [200, {'content-length' => "untrusted input#{line_ending}Cookie: hack"}, ["Hello"]] }
++      assert_does_not_allow_http_injection(app)
++    end
+   end
+ end
diff -Nru puma-3.12.0/debian/patches/series puma-3.12.0/debian/patches/series
--- puma-3.12.0/debian/patches/series	2020-03-04 00:15:43.000000000 +0100
+++ puma-3.12.0/debian/patches/series	2020-10-15 23:39:36.000000000 +0200
@@ -7,3 +7,7 @@
 0008-fix-ssl-tests.patch
 0009-disable-tests-failing-in-single-cpu.patch
 CVE-2019-16770.patch
+CVE-2020-5247.patch
+CVE-2020-5249.patch
+CVE-2020-11076.patch
+CVE-2020-11077.patch

Reply to: