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 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
 
@@ -21,7 +21,11 @@ module Rack
21
21
  end
22
22
 
23
23
  def scheme
24
- @scheme ||= parts.first.downcase.to_sym
24
+ @scheme ||=
25
+ begin
26
+ s = parts.first.downcase
27
+ Rack::Auth.schemes.include?(s) ? s.to_sym : s
28
+ end
25
29
  end
26
30
 
27
31
  def params
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
- parts.inject(0) do |depth, part|
51
- case part
52
- when '', '.'
53
- depth
54
- when '..'
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, *parts)
57
+ @path = F.join(@root, *clean)
63
58
 
64
59
  available = begin
65
60
  F.file?(@path) && F.readable?(@path)
@@ -117,7 +117,7 @@ module Rack
117
117
 
118
118
  if session_data && digest
119
119
  ok = @secrets.any? do |secret|
120
- secret && digest == generate_hmac(session_data, secret)
120
+ secret && Rack::Utils.secure_compare(digest, generate_hmac(session_data, secret))
121
121
  end
122
122
  end
123
123
 
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
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "rack"
3
- s.version = "1.4.3"
3
+ s.version = "1.4.5"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.summary = "a modular Ruby webserver interface"
6
6
 
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 {|env| throw :bacon }, lock)
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
@@ -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 "/tmp/rack_sendfile"
15
+ FileUtils.touch File.join(Dir.tmpdir, "rack_sendfile")
15
16
  res = ['Hello World']
16
- def res.to_path ; "/tmp/rack_sendfile" ; end
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 '/tmp/rack_sendfile'
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 '/tmp/rack_sendfile'
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' => '/tmp/=/foo/bar/'
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: 1
4
+ hash: 13
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 4
9
- - 3
10
- version: 1.4.3
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-01-07 00:00:00 Z
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: -1379016806
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