From b5cbe4365e2c3fb4cddc3570d4643bcc4834ab25 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Wed, 20 Jan 2021 08:26:13 -0800 Subject: [PATCH] Default to & as separator instead of either & or ; Allowing ; as separator by default can lead to web cache poisoning. Fixes #1732 --- lib/rack/query_parser.rb | 9 ++++----- lib/rack/request.rb | 2 +- test/spec_request.rb | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/rack/query_parser.rb b/lib/rack/query_parser.rb index dbbb18e5a..388e083c7 100644 --- a/lib/rack/query_parser.rb +++ b/lib/rack/query_parser.rb @@ -4,7 +4,7 @@ module Rack class QueryParser (require_relative 'core_ext/regexp'; using ::Rack::RegexpExtensions) if RUBY_VERSION < '2.4' - DEFAULT_SEP = /[&;] */n + DEFAULT_SEP = /[&] */n COMMON_SEP = { ";" => /[;] */n, ";," => /[;,] */n, "&" => /[&] */n } # ParameterTypeError is the error that is raised when incoming structural @@ -29,10 +29,9 @@ def initialize(params_class, key_space_limit, param_depth_limit) end # Stolen from Mongrel, with some small modifications: - # Parses a query string by breaking it up at the '&' - # and ';' characters. You can also use this to parse - # cookies by changing the characters used in the second - # parameter (which defaults to '&;'). + # Parses a query string by breaking it up at the '&'. You can also use this + # to parse cookies by changing the characters used in the second parameter + # (which defaults to '&'). def parse_query(qs, d = nil, &unescaper) unescaper ||= method(:unescape) diff --git a/lib/rack/request.rb b/lib/rack/request.rb index 74377ede3..541c3801b 100644 --- a/lib/rack/request.rb +++ b/lib/rack/request.rb @@ -427,7 +427,7 @@ def GET if get_header(RACK_REQUEST_QUERY_STRING) == query_string get_header(RACK_REQUEST_QUERY_HASH) else - query_hash = parse_query(query_string, '&;') + query_hash = parse_query(query_string, '&') set_header(RACK_REQUEST_QUERY_STRING, query_string) set_header(RACK_REQUEST_QUERY_HASH, query_hash) end diff --git a/test/spec_request.rb b/test/spec_request.rb index 6b73cd5b5..6bc77b01a 100644 --- a/test/spec_request.rb +++ b/test/spec_request.rb @@ -308,12 +308,12 @@ def initialize(*) req.params[:quux].must_equal "bla" end - it "use semi-colons as separators for query strings in GET" do + it "does not use semi-colons as separators for query strings in GET" do req = make_request(Rack::MockRequest.env_for("/?foo=bar&quux=b;la;wun=duh")) req.query_string.must_equal "foo=bar&quux=b;la;wun=duh" - req.GET.must_equal "foo" => "bar", "quux" => "b", "la" => nil, "wun" => "duh" + req.GET.must_equal "foo" => "bar", "quux" => "b;la;wun=duh" req.POST.must_be :empty? - req.params.must_equal "foo" => "bar", "quux" => "b", "la" => nil, "wun" => "duh" + req.params.must_equal "foo" => "bar", "quux" => "b;la;wun=duh" end it "limit the keys from the GET query string" do