diff options
| author | Jeremy Evans <code@jeremyevans.net> | 2020-01-15 11:03:54 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-01-15 11:03:54 -0800 |
| commit | d2b8f254a3671a19841e4e9284411b2d414f2675 (patch) | |
| tree | 41b122823aeb683cb1d95febf9a1d22a953f94b8 | |
| parent | f83d84117724ff55b7e7bab32439394513d67ea2 (diff) | |
| parent | 543256fcdcc518c6319f5599c19507410688615e (diff) | |
| download | rack-d2b8f254a3671a19841e4e9284411b2d414f2675.tar.gz | |
Merge pull request #1487 from jeremyevans/limit-doc-spec
| -rw-r--r-- | README.rdoc | 22 | ||||
| -rw-r--r-- | test/spec_request.rb | 25 |
2 files changed, 44 insertions, 3 deletions
diff --git a/README.rdoc b/README.rdoc index b14789d7..e13dc592 100644 --- a/README.rdoc +++ b/README.rdoc @@ -136,10 +136,26 @@ e.g: === key_space_limit -The default number of bytes to allow a single parameter key to take up. -This helps prevent a rogue client from flooding a Request. +The default number of bytes to allow all parameters keys in a given parameter hash to take up. +Does not affect nested parameter hashes, so doesn't actually prevent an attacker from using +more than this many bytes for parameter keys. -Default to 65536 characters (4 kiB in worst case). +Defaults to 65536 characters. + +=== param_depth_limit + +The maximum amount of nesting allowed in parameters. +For example, if set to 3, this query string would be allowed: + + ?a[b][c]=d + +but this query string would not be allowed: + + ?a[b][c][d]=e + +Limiting the depth prevents a possible stack overflow when parsing parameters. + +Defaults to 100. === multipart_part_limit diff --git a/test/spec_request.rb b/test/spec_request.rb index 2795966f..5f418ffd 100644 --- a/test/spec_request.rb +++ b/test/spec_request.rb @@ -282,6 +282,31 @@ class RackRequestTest < Minitest::Spec end end + it "limit the allowed parameter depth when parsing parameters" do + env = Rack::MockRequest.env_for("/?a#{'[a]' * 110}=b") + req = make_request(env) + lambda { req.GET }.must_raise RangeError + + env = Rack::MockRequest.env_for("/?a#{'[a]' * 90}=b") + req = make_request(env) + params = req.GET + 90.times { params = params['a'] } + params['a'].must_equal 'b' + + old, Rack::Utils.param_depth_limit = Rack::Utils.param_depth_limit, 3 + begin + env = Rack::MockRequest.env_for("/?a[a][a]=b") + req = make_request(env) + req.GET['a']['a']['a'].must_equal 'b' + + env = Rack::MockRequest.env_for("/?a[a][a][a]=b") + req = make_request(env) + lambda { make_request(env).GET }.must_raise RangeError + ensure + Rack::Utils.param_depth_limit = old + end + end + it "not unify GET and POST when calling params" do mr = Rack::MockRequest.env_for("/?foo=quux", "REQUEST_METHOD" => 'POST', |
