rack 1.4.3 → 1.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +27 -0
- data/lib/rack/auth/abstract/request.rb +5 -1
- data/lib/rack/file.rb +6 -11
- data/lib/rack/session/cookie.rb +1 -1
- data/lib/rack/utils.rb +12 -1
- data/lib/rack.rb +12 -0
- data/rack.gemspec +1 -1
- data/test/spec_auth.rb +57 -0
- data/test/spec_lock.rb +1 -1
- data/test/spec_sendfile.rb +6 -5
- data/test/spec_utils.rb +5 -0
- metadata +7 -5
data/README.rdoc
CHANGED
|
@@ -479,11 +479,38 @@ run on port 11211) and memcache-client installed.
|
|
|
479
479
|
* January 7th, 2013: Thirty first public release 1.4.3
|
|
480
480
|
* Security: Prevent unbounded reads in large multipart boundaries
|
|
481
481
|
|
|
482
|
+
* January 13th, 2013: Thirty second public release 1.4.4, 1.3.9, 1.2.7, 1.1.5
|
|
483
|
+
* [SEC] Rack::Auth::AbstractRequest no longer symbolizes arbitrary strings
|
|
484
|
+
* Fixed erroneous test case in the 1.3.x series
|
|
485
|
+
|
|
486
|
+
* February 7th, Thirty fifth public release 1.1.6, 1.2.8, 1.3.10
|
|
487
|
+
* Fix CVE-2013-0263, timing attack against Rack::Session::Cookie
|
|
488
|
+
|
|
489
|
+
* February 7th, Thirty fifth public release 1.4.5
|
|
490
|
+
* Fix CVE-2013-0263, timing attack against Rack::Session::Cookie
|
|
491
|
+
* Fix CVE-2013-0262, symlink path traversal in Rack::File
|
|
492
|
+
|
|
493
|
+
* February 7th, Thirty fifth public release 1.5.2
|
|
494
|
+
* Fix CVE-2013-0263, timing attack against Rack::Session::Cookie
|
|
495
|
+
* Fix CVE-2013-0262, symlink path traversal in Rack::File
|
|
496
|
+
* Add various methods to Session for enhanced Rails compatibility
|
|
497
|
+
* Request#trusted_proxy? now only matches whole stirngs
|
|
498
|
+
* Add JSON cookie coder, to be default in Rack 1.6+ due to security concerns
|
|
499
|
+
* URLMap host matching in environments that don't set the Host header fixed
|
|
500
|
+
* Fix a race condition that could result in overwritten pidfiles
|
|
501
|
+
* Various documentation additions
|
|
502
|
+
|
|
482
503
|
== Contact
|
|
483
504
|
|
|
484
505
|
Please post bugs, suggestions and patches to
|
|
485
506
|
the bug tracker at <http://github.com/rack/rack/issues>.
|
|
486
507
|
|
|
508
|
+
Please post security related bugs and suggestions to the core team at
|
|
509
|
+
<https://groups.google.com/group/rack-core> or rack-core@googlegroups.com. Due
|
|
510
|
+
to wide usage of the library, it is strongly preferred that we manage timing in
|
|
511
|
+
order to provide viable patches at the time of disclosure. Your assistance in
|
|
512
|
+
this matter is greatly appreciated.
|
|
513
|
+
|
|
487
514
|
Mailing list archives are available at
|
|
488
515
|
<http://groups.google.com/group/rack-devel>.
|
|
489
516
|
|
data/lib/rack/file.rb
CHANGED
|
@@ -47,19 +47,14 @@ module Rack
|
|
|
47
47
|
@path_info = Utils.unescape(env["PATH_INFO"])
|
|
48
48
|
parts = @path_info.split SEPS
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return fail(404, "Not Found") if depth - 1 < 0
|
|
56
|
-
depth - 1
|
|
57
|
-
else
|
|
58
|
-
depth + 1
|
|
59
|
-
end
|
|
50
|
+
clean = []
|
|
51
|
+
|
|
52
|
+
parts.each do |part|
|
|
53
|
+
next if part.empty? || part == '.'
|
|
54
|
+
part == '..' ? clean.pop : clean << part
|
|
60
55
|
end
|
|
61
56
|
|
|
62
|
-
@path = F.join(@root, *
|
|
57
|
+
@path = F.join(@root, *clean)
|
|
63
58
|
|
|
64
59
|
available = begin
|
|
65
60
|
F.file?(@path) && F.readable?(@path)
|
data/lib/rack/session/cookie.rb
CHANGED
data/lib/rack/utils.rb
CHANGED
|
@@ -5,7 +5,6 @@ require 'tempfile'
|
|
|
5
5
|
require 'rack/multipart'
|
|
6
6
|
|
|
7
7
|
major, minor, patch = RUBY_VERSION.split('.').map { |v| v.to_i }
|
|
8
|
-
ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
|
9
8
|
|
|
10
9
|
if major == 1 && minor < 9
|
|
11
10
|
require 'rack/backports/uri/common_18'
|
|
@@ -343,6 +342,18 @@ module Rack
|
|
|
343
342
|
end
|
|
344
343
|
module_function :byte_ranges
|
|
345
344
|
|
|
345
|
+
# Constant time string comparison.
|
|
346
|
+
def secure_compare(a, b)
|
|
347
|
+
return false unless bytesize(a) == bytesize(b)
|
|
348
|
+
|
|
349
|
+
l = a.unpack("C*")
|
|
350
|
+
|
|
351
|
+
r, i = 0, -1
|
|
352
|
+
b.each_byte { |v| r |= v ^ l[i+=1] }
|
|
353
|
+
r == 0
|
|
354
|
+
end
|
|
355
|
+
module_function :secure_compare
|
|
356
|
+
|
|
346
357
|
# Context allows the use of a compatible middleware at different points
|
|
347
358
|
# in a request handling stack. A compatible middleware must define
|
|
348
359
|
# #context which should take the arguments env and app. The first of which
|
data/lib/rack.rb
CHANGED
|
@@ -73,6 +73,18 @@ module Rack
|
|
|
73
73
|
autoload :Params, "rack/auth/digest/params"
|
|
74
74
|
autoload :Request, "rack/auth/digest/request"
|
|
75
75
|
end
|
|
76
|
+
|
|
77
|
+
# Not all of the following schemes are "standards", but they are used often.
|
|
78
|
+
@schemes = %w[basic digest bearer mac token oauth oauth2]
|
|
79
|
+
|
|
80
|
+
def self.add_scheme scheme
|
|
81
|
+
@schemes << scheme
|
|
82
|
+
@schemes.uniq!
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def self.schemes
|
|
86
|
+
@schemes.dup
|
|
87
|
+
end
|
|
76
88
|
end
|
|
77
89
|
|
|
78
90
|
module Session
|
data/rack.gemspec
CHANGED
data/test/spec_auth.rb
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'rack'
|
|
2
|
+
|
|
3
|
+
describe Rack::Auth do
|
|
4
|
+
it "should have all common authentication schemes" do
|
|
5
|
+
Rack::Auth.schemes.should.include? 'basic'
|
|
6
|
+
Rack::Auth.schemes.should.include? 'digest'
|
|
7
|
+
Rack::Auth.schemes.should.include? 'bearer'
|
|
8
|
+
Rack::Auth.schemes.should.include? 'token'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should allow registration of new auth schemes" do
|
|
12
|
+
Rack::Auth.schemes.should.not.include "test"
|
|
13
|
+
Rack::Auth.add_scheme "test"
|
|
14
|
+
Rack::Auth.schemes.should.include "test"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe Rack::Auth::AbstractRequest do
|
|
19
|
+
it "should symbolize known auth schemes" do
|
|
20
|
+
env = Rack::MockRequest.env_for('/')
|
|
21
|
+
env['HTTP_AUTHORIZATION'] = 'Basic aXJyZXNwb25zaWJsZQ=='
|
|
22
|
+
req = Rack::Auth::AbstractRequest.new(env)
|
|
23
|
+
req.scheme.should.equal :basic
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
env['HTTP_AUTHORIZATION'] = 'Digest aXJyZXNwb25zaWJsZQ=='
|
|
27
|
+
req = Rack::Auth::AbstractRequest.new(env)
|
|
28
|
+
req.scheme.should.equal :digest
|
|
29
|
+
|
|
30
|
+
env['HTTP_AUTHORIZATION'] = 'Bearer aXJyZXNwb25zaWJsZQ=='
|
|
31
|
+
req = Rack::Auth::AbstractRequest.new(env)
|
|
32
|
+
req.scheme.should.equal :bearer
|
|
33
|
+
|
|
34
|
+
env['HTTP_AUTHORIZATION'] = 'MAC aXJyZXNwb25zaWJsZQ=='
|
|
35
|
+
req = Rack::Auth::AbstractRequest.new(env)
|
|
36
|
+
req.scheme.should.equal :mac
|
|
37
|
+
|
|
38
|
+
env['HTTP_AUTHORIZATION'] = 'Token aXJyZXNwb25zaWJsZQ=='
|
|
39
|
+
req = Rack::Auth::AbstractRequest.new(env)
|
|
40
|
+
req.scheme.should.equal :token
|
|
41
|
+
|
|
42
|
+
env['HTTP_AUTHORIZATION'] = 'OAuth aXJyZXNwb25zaWJsZQ=='
|
|
43
|
+
req = Rack::Auth::AbstractRequest.new(env)
|
|
44
|
+
req.scheme.should.equal :oauth
|
|
45
|
+
|
|
46
|
+
env['HTTP_AUTHORIZATION'] = 'OAuth2 aXJyZXNwb25zaWJsZQ=='
|
|
47
|
+
req = Rack::Auth::AbstractRequest.new(env)
|
|
48
|
+
req.scheme.should.equal :oauth2
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should not symbolize unknown auth schemes" do
|
|
52
|
+
env = Rack::MockRequest.env_for('/')
|
|
53
|
+
env['HTTP_AUTHORIZATION'] = 'magic aXJyZXNwb25zaWJsZQ=='
|
|
54
|
+
req = Rack::Auth::AbstractRequest.new(env)
|
|
55
|
+
req.scheme.should == "magic"
|
|
56
|
+
end
|
|
57
|
+
end
|
data/test/spec_lock.rb
CHANGED
|
@@ -142,7 +142,7 @@ describe Rack::Lock do
|
|
|
142
142
|
should "unlock if the app throws" do
|
|
143
143
|
lock = Lock.new
|
|
144
144
|
env = Rack::MockRequest.env_for("/")
|
|
145
|
-
app = lock_app(lambda {|
|
|
145
|
+
app = lock_app(lambda {|_| throw :bacon }, lock)
|
|
146
146
|
lambda { app.call(env) }.should.throw(:bacon)
|
|
147
147
|
lock.synchronized.should.equal false
|
|
148
148
|
end
|
data/test/spec_sendfile.rb
CHANGED
|
@@ -2,6 +2,7 @@ require 'fileutils'
|
|
|
2
2
|
require 'rack/lint'
|
|
3
3
|
require 'rack/sendfile'
|
|
4
4
|
require 'rack/mock'
|
|
5
|
+
require 'tmpdir'
|
|
5
6
|
|
|
6
7
|
describe Rack::File do
|
|
7
8
|
should "respond to #to_path" do
|
|
@@ -11,9 +12,9 @@ end
|
|
|
11
12
|
|
|
12
13
|
describe Rack::Sendfile do
|
|
13
14
|
def sendfile_body
|
|
14
|
-
FileUtils.touch "
|
|
15
|
+
FileUtils.touch File.join(Dir.tmpdir, "rack_sendfile")
|
|
15
16
|
res = ['Hello World']
|
|
16
|
-
def res.to_path ; "
|
|
17
|
+
def res.to_path ; File.join(Dir.tmpdir, "rack_sendfile") ; end
|
|
17
18
|
res
|
|
18
19
|
end
|
|
19
20
|
|
|
@@ -44,7 +45,7 @@ describe Rack::Sendfile do
|
|
|
44
45
|
response.should.be.ok
|
|
45
46
|
response.body.should.be.empty
|
|
46
47
|
response.headers['Content-Length'].should.equal '0'
|
|
47
|
-
response.headers['X-Sendfile'].should.equal
|
|
48
|
+
response.headers['X-Sendfile'].should.equal File.join(Dir.tmpdir, "rack_sendfile")
|
|
48
49
|
end
|
|
49
50
|
end
|
|
50
51
|
|
|
@@ -53,14 +54,14 @@ describe Rack::Sendfile do
|
|
|
53
54
|
response.should.be.ok
|
|
54
55
|
response.body.should.be.empty
|
|
55
56
|
response.headers['Content-Length'].should.equal '0'
|
|
56
|
-
response.headers['X-Lighttpd-Send-File'].should.equal
|
|
57
|
+
response.headers['X-Lighttpd-Send-File'].should.equal File.join(Dir.tmpdir, "rack_sendfile")
|
|
57
58
|
end
|
|
58
59
|
end
|
|
59
60
|
|
|
60
61
|
it "sets X-Accel-Redirect response header and discards body" do
|
|
61
62
|
headers = {
|
|
62
63
|
'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect',
|
|
63
|
-
'HTTP_X_ACCEL_MAPPING' =>
|
|
64
|
+
'HTTP_X_ACCEL_MAPPING' => "#{Dir.tmpdir}/=/foo/bar/"
|
|
64
65
|
}
|
|
65
66
|
request headers do |response|
|
|
66
67
|
response.should.be.ok
|
data/test/spec_utils.rb
CHANGED
|
@@ -331,6 +331,11 @@ describe Rack::Utils do
|
|
|
331
331
|
Rack::Utils.bytesize("FOO\xE2\x82\xAC").should.equal 6
|
|
332
332
|
end
|
|
333
333
|
|
|
334
|
+
should "should perform constant time string comparison" do
|
|
335
|
+
Rack::Utils.secure_compare('a', 'a').should.equal true
|
|
336
|
+
Rack::Utils.secure_compare('a', 'b').should.equal false
|
|
337
|
+
end
|
|
338
|
+
|
|
334
339
|
should "return status code for integer" do
|
|
335
340
|
Rack::Utils.status_code(200).should.equal 200
|
|
336
341
|
end
|
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: 13
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
7
|
- 1
|
|
8
8
|
- 4
|
|
9
|
-
-
|
|
10
|
-
version: 1.4.
|
|
9
|
+
- 5
|
|
10
|
+
version: 1.4.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: 2013-
|
|
18
|
+
date: 2013-02-08 00:00:00 Z
|
|
19
19
|
dependencies:
|
|
20
20
|
- !ruby/object:Gem::Dependency
|
|
21
21
|
name: bacon
|
|
@@ -81,7 +81,7 @@ dependencies:
|
|
|
81
81
|
requirements:
|
|
82
82
|
- - ">="
|
|
83
83
|
- !ruby/object:Gem::Version
|
|
84
|
-
hash:
|
|
84
|
+
hash: 3904189667
|
|
85
85
|
segments:
|
|
86
86
|
- 1
|
|
87
87
|
- 2
|
|
@@ -237,6 +237,7 @@ files:
|
|
|
237
237
|
- test/multipart/webkit
|
|
238
238
|
- test/rackup/config.ru
|
|
239
239
|
- test/registering_handler/rack/handler/registering_myself.rb
|
|
240
|
+
- test/spec_auth.rb
|
|
240
241
|
- test/spec_auth_basic.rb
|
|
241
242
|
- test/spec_auth_digest.rb
|
|
242
243
|
- test/spec_body_proxy.rb
|
|
@@ -328,6 +329,7 @@ signing_key:
|
|
|
328
329
|
specification_version: 3
|
|
329
330
|
summary: a modular Ruby webserver interface
|
|
330
331
|
test_files:
|
|
332
|
+
- test/spec_auth.rb
|
|
331
333
|
- test/spec_auth_basic.rb
|
|
332
334
|
- test/spec_auth_digest.rb
|
|
333
335
|
- test/spec_body_proxy.rb
|