rack 1.2.4 → 1.2.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rack might be problematic. Click here for more details.
- data/README +4 -0
- data/lib/rack/lock.rb +2 -0
- data/lib/rack/mime.rb +2 -0
- data/lib/rack/utils.rb +41 -1
- data/rack.gemspec +1 -1
- data/test/spec_request.rb +49 -0
- metadata +5 -5
data/README
CHANGED
@@ -344,6 +344,10 @@ run on port 11211) and memcache-client installed.
|
|
344
344
|
* September 16, 2011: Eighteenth public release 1.2.4
|
345
345
|
* Fix a bug with MRI regex engine to prevent XSS by malformed unicode
|
346
346
|
|
347
|
+
* December 28th, 2011: Twenty second public release: 1.2.5
|
348
|
+
* Security fix. http://www.ocert.org/advisories/ocert-2011-003.html
|
349
|
+
Further information here: http://jruby.org/2011/12/27/jruby-1-6-5-1
|
350
|
+
|
347
351
|
== Contact
|
348
352
|
|
349
353
|
Please post bugs, suggestions and patches to
|
data/lib/rack/lock.rb
CHANGED
data/lib/rack/mime.rb
CHANGED
@@ -70,6 +70,7 @@ module Rack
|
|
70
70
|
".dll" => "application/x-msdownload",
|
71
71
|
".dmg" => "application/octet-stream",
|
72
72
|
".doc" => "application/msword",
|
73
|
+
".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
73
74
|
".dot" => "application/msword",
|
74
75
|
".dtd" => "application/xml-dtd",
|
75
76
|
".dvi" => "application/x-dvi",
|
@@ -196,6 +197,7 @@ module Rack
|
|
196
197
|
".xbm" => "image/x-xbitmap",
|
197
198
|
".xhtml" => "application/xhtml+xml",
|
198
199
|
".xls" => "application/vnd.ms-excel",
|
200
|
+
".xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
199
201
|
".xml" => "application/xml",
|
200
202
|
".xpm" => "image/x-xpixmap",
|
201
203
|
".xsl" => "application/xml",
|
data/lib/rack/utils.rb
CHANGED
@@ -29,6 +29,14 @@ module Rack
|
|
29
29
|
|
30
30
|
DEFAULT_SEP = /[&;] */n
|
31
31
|
|
32
|
+
class << self
|
33
|
+
attr_accessor :key_space_limit
|
34
|
+
end
|
35
|
+
|
36
|
+
# The default number of bytes to allow parameter keys to take up.
|
37
|
+
# This helps prevent a rogue client from flooding a Request.
|
38
|
+
self.key_space_limit = 65536
|
39
|
+
|
32
40
|
# Stolen from Mongrel, with some small modifications:
|
33
41
|
# Parses a query string by breaking it up at the '&'
|
34
42
|
# and ';' characters. You can also use this to parse
|
@@ -37,8 +45,19 @@ module Rack
|
|
37
45
|
def parse_query(qs, d = nil)
|
38
46
|
params = {}
|
39
47
|
|
48
|
+
max_key_space = Utils.key_space_limit
|
49
|
+
bytes = 0
|
50
|
+
|
40
51
|
(qs || '').split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p|
|
41
52
|
k, v = p.split('=', 2).map { |x| unescape(x) }
|
53
|
+
|
54
|
+
if k
|
55
|
+
bytes += k.size
|
56
|
+
if bytes > max_key_space
|
57
|
+
raise RangeError, "exceeded available parameter key space"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
42
61
|
if cur = params[k]
|
43
62
|
if cur.class == Array
|
44
63
|
params[k] << v
|
@@ -57,8 +76,19 @@ module Rack
|
|
57
76
|
def parse_nested_query(qs, d = nil)
|
58
77
|
params = {}
|
59
78
|
|
79
|
+
max_key_space = Utils.key_space_limit
|
80
|
+
bytes = 0
|
81
|
+
|
60
82
|
(qs || '').split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p|
|
61
83
|
k, v = unescape(p).split('=', 2)
|
84
|
+
|
85
|
+
if k
|
86
|
+
bytes += k.size
|
87
|
+
if bytes > max_key_space
|
88
|
+
raise RangeError, "exceeded available parameter key space"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
62
92
|
normalize_params(params, k, v)
|
63
93
|
end
|
64
94
|
|
@@ -503,6 +533,9 @@ module Rack
|
|
503
533
|
|
504
534
|
rx = /(?:#{EOL})?#{Regexp.quote boundary}(#{EOL}|--)/n
|
505
535
|
|
536
|
+
max_key_space = Utils.key_space_limit
|
537
|
+
bytes = 0
|
538
|
+
|
506
539
|
loop {
|
507
540
|
head = nil
|
508
541
|
body = ''
|
@@ -537,7 +570,14 @@ module Rack
|
|
537
570
|
content_type = head[/Content-Type: (.*)#{EOL}/ni, 1]
|
538
571
|
name = head[/Content-Disposition:.*\s+name="?([^\";]*)"?/ni, 1] || head[/Content-ID:\s*([^#{EOL}]*)/ni, 1]
|
539
572
|
|
540
|
-
if
|
573
|
+
if name
|
574
|
+
bytes += name.size
|
575
|
+
if bytes > max_key_space
|
576
|
+
raise RangeError, "exceeded available parameter key space"
|
577
|
+
end
|
578
|
+
end
|
579
|
+
|
580
|
+
if content_type || filename
|
541
581
|
body = Tempfile.new("RackMultipart")
|
542
582
|
body.binmode if body.respond_to?(:binmode)
|
543
583
|
end
|
data/rack.gemspec
CHANGED
data/test/spec_request.rb
CHANGED
@@ -78,6 +78,32 @@ describe Rack::Request do
|
|
78
78
|
req.params.should.equal "foo" => "bar", "quux" => "bla"
|
79
79
|
end
|
80
80
|
|
81
|
+
should "limit the keys from the GET query string" do
|
82
|
+
env = Rack::MockRequest.env_for("/?foo=bar")
|
83
|
+
|
84
|
+
old, Rack::Utils.key_space_limit = Rack::Utils.key_space_limit, 1
|
85
|
+
begin
|
86
|
+
req = Rack::Request.new(env)
|
87
|
+
lambda { req.GET }.should.raise(RangeError)
|
88
|
+
ensure
|
89
|
+
Rack::Utils.key_space_limit = old
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
should "limit the keys from the POST form data" do
|
94
|
+
env = Rack::MockRequest.env_for("",
|
95
|
+
"REQUEST_METHOD" => 'POST',
|
96
|
+
:input => "foo=bar&quux=bla")
|
97
|
+
|
98
|
+
old, Rack::Utils.key_space_limit = Rack::Utils.key_space_limit, 1
|
99
|
+
begin
|
100
|
+
req = Rack::Request.new(env)
|
101
|
+
lambda { req.POST }.should.raise(RangeError)
|
102
|
+
ensure
|
103
|
+
Rack::Utils.key_space_limit = old
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
81
107
|
should "parse POST data with explicit content type regardless of method" do
|
82
108
|
req = Rack::Request.new \
|
83
109
|
Rack::MockRequest.env_for("/",
|
@@ -294,6 +320,29 @@ describe Rack::Request do
|
|
294
320
|
req.media_type_params['bling'].should.equal 'bam'
|
295
321
|
end
|
296
322
|
|
323
|
+
should "raise RangeError if the key space is exhausted" do
|
324
|
+
input = <<EOF
|
325
|
+
--AaB03x\r
|
326
|
+
Content-Disposition: form-data; name="text"\r
|
327
|
+
Content-Type: text/plain; charset=US-ASCII\r
|
328
|
+
\r
|
329
|
+
contents\r
|
330
|
+
--AaB03x--\r
|
331
|
+
EOF
|
332
|
+
|
333
|
+
env = Rack::MockRequest.env_for("/",
|
334
|
+
"CONTENT_TYPE" => "multipart/form-data, boundary=AaB03x",
|
335
|
+
"CONTENT_LENGTH" => input.size,
|
336
|
+
:input => input)
|
337
|
+
|
338
|
+
old, Rack::Utils.key_space_limit = Rack::Utils.key_space_limit, 1
|
339
|
+
begin
|
340
|
+
lambda { Rack::Utils::Multipart.parse_multipart(env) }.should.raise(RangeError)
|
341
|
+
ensure
|
342
|
+
Rack::Utils.key_space_limit = old
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
297
346
|
should "parse multipart form data" do
|
298
347
|
# Adapted from RFC 1867.
|
299
348
|
input = <<EOF
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 1.2.
|
9
|
+
- 5
|
10
|
+
version: 1.2.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Christian Neukirchen
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-12-28 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: bacon
|
@@ -284,7 +284,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
284
284
|
requirements: []
|
285
285
|
|
286
286
|
rubyforge_project: rack
|
287
|
-
rubygems_version: 1.8.
|
287
|
+
rubygems_version: 1.8.12
|
288
288
|
signing_key:
|
289
289
|
specification_version: 3
|
290
290
|
summary: a modular Ruby webserver interface
|