From 5ccca4722668083732ea2d35c56565fcc25312f8 Mon Sep 17 00:00:00 2001 From: Matt Langlois <fletchto99@gmail.com> Date: Fri, 12 Jun 2020 12:57:34 -0600 Subject: [PATCH] When parsing cookies, only decode the values Patch utils to fix cookie parsing [CVE-2020-8184] --- lib/rack/utils.rb | 8 ++++++-- test/spec_utils.rb | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/rack/utils.rb b/lib/rack/utils.rb index f033c900d..d3b3b1d42 100644 --- a/lib/rack/utils.rb +++ b/lib/rack/utils.rb @@ -210,8 +210,12 @@ # the Cookie header such that those with more specific Path attributes # precede those with less specific. Ordering with respect to other # attributes (e.g., Domain) is unspecified. - cookies = parse_query(header, ';,') { |s| unescape(s) rescue s } - cookies.each_with_object({}) { |(k,v), hash| hash[k] = Array === v ? v.first : v } + return {} unless header + header.split(/[;] */n).each_with_object({}) do |cookie, cookies| + next if cookie.empty? + key, value = cookie.split('=', 2) + cookies[key] = (unescape(value) rescue value) unless cookies.key?(key) + end end module_function :parse_cookies_header diff --git a/test/spec_utils.rb b/test/spec_utils.rb index b39f4a00d..273dc6c1f 100644 --- a/test/spec_utils.rb +++ b/test/spec_utils.rb @@ -505,6 +505,9 @@ env = Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=bar").freeze Rack::Utils.parse_cookies(env).must_equal({"foo" => "bar"}) + + env = Rack::MockRequest.env_for("", "HTTP_COOKIE" => "%66oo=baz;foo=bar") + Rack::Utils.parse_cookies(env).must_equal({ "%66oo" => "baz", "foo" => "bar" }) end it "adds new cookies to nil header" do