Package: release.debian.org
Severity: normal
User: release.debian....@packages.debian.org
Usertags: unblock

Dear release team,

Please unblock package ruby-rack, which fixes grave security bugs:
#698440
#700173
#700226

3 BTS contains 5 CVE adviseries tracked as:
https://security-tracker.debian.org/tracker/source-package/ruby-rack
All patches are backported from upstream fix.

I've prepared nmu with maintainer's permission, and debdiff is below:
(or, staging at mentors at: 
http://mentors.debian.net/debian/pool/main/r/ruby-rack/ruby-rack_1.4.1-2.1.dsc )
I'll ask for upload sponsor after this request would be approved.

diff -Nru ruby-rack-1.4.1/debian/changelog ruby-rack-1.4.1/debian/changelog
--- ruby-rack-1.4.1/debian/changelog    2012-06-26 03:07:51.000000000 +0900
+++ ruby-rack-1.4.1/debian/changelog    2013-02-20 21:21:25.000000000 +0900
@@ -1,3 +1,19 @@
+ruby-rack (1.4.1-2.1) testing-security; urgency=high
+
+  [ KURASHIKI Satoru ]
+  * Non-maintainer upload.
+  * Create cherry-picked patches for Security Fix (Closes: #700173 #700226).
+    - CVE-2013-0262: 0004-Prevent-symlink-path-traversals.patch
+    - CVE-2013-0263: 0005-Use-secure_compare-for-hmac-comparison.patch
+
+  [ Youhei SASAKI ]
+  * Create cherry-picked patches for Security Fix (Closes: #698440).
+    - CVE-2012-6109: 0001-Fix-parsing-performance-for-unquoted-filenames.patch
+    - CVE-2013-0183: 0002-multipart-parser-avoid-unbounded-gets-method.patch
+    - CVE-2013-0184: 0003-Reimplement-auth-scheme-fix.patch
+
+ -- KURASHIKI Satoru <lur...@gmail.com>  Wed, 20 Feb 2013 20:56:31 +0900
+
 ruby-rack (1.4.1-2) unstable; urgency=low
 
   * Bump build dependency on gem2deb to >= 0.3.0~
diff -Nru 
ruby-rack-1.4.1/debian/patches/0001-Fix-parsing-performance-for-unquoted-filenames.patch
 
ruby-rack-1.4.1/debian/patches/0001-Fix-parsing-performance-for-unquoted-filenames.patch
--- 
ruby-rack-1.4.1/debian/patches/0001-Fix-parsing-performance-for-unquoted-filenames.patch
    1970-01-01 09:00:00.000000000 +0900
+++ 
ruby-rack-1.4.1/debian/patches/0001-Fix-parsing-performance-for-unquoted-filenames.patch
    2013-02-10 23:07:16.000000000 +0900
@@ -0,0 +1,67 @@
+From: James Tucker <jftuc...@gmail.com>
+Date: Sun, 13 May 2012 15:02:17 -0700
+Subject: Fix parsing performance for unquoted filenames
+
+Special thanks to Paul Rogers & Eric Wong
+
+Origin: upstream, 
https://github.com/rack/rack/commit/4fc44671b3cad569421f4f8b775c0590b86f575e
+Bug: https://security-tracker.debian.org/tracker/CVE-2012-6109
+Bug-Debian: http://bugs.debian.org/698440
+
+---
+ lib/rack/multipart.rb  |    4 ++--
+ test/spec_multipart.rb |   21 +++++++++++++++++++++
+ 2 files changed, 23 insertions(+), 2 deletions(-)
+
+diff --git a/lib/rack/multipart.rb b/lib/rack/multipart.rb
+index 3777106..6849248 100644
+--- a/lib/rack/multipart.rb
++++ b/lib/rack/multipart.rb
+@@ -12,7 +12,7 @@ module Rack
+     MULTIPART = %r|\Amultipart/.*boundary=\"?([^\";,]+)\"?|n
+     TOKEN = /[^\s()<>,;:\\"\/\[\]?=]+/
+     CONDISP = /Content-Disposition:\s*#{TOKEN}\s*/i
+-    DISPPARM = /;\s*(#{TOKEN})=("(?:\\"|[^"])*"|#{TOKEN})*/
++    DISPPARM = /;\s*(#{TOKEN})=("(?:\\"|[^"])*"|#{TOKEN})/
+     RFC2183 = /^#{CONDISP}(#{DISPPARM})+$/i
+     BROKEN_QUOTED = 
/^#{CONDISP}.*;\sfilename="(.*?)"(?:\s*$|\s*;\s*#{TOKEN}=)/i
+     BROKEN_UNQUOTED = /^#{CONDISP}.*;\sfilename=(#{TOKEN})/i
+@@ -31,4 +31,4 @@ module Rack
+     end
+
+   end
+-end
+\ No newline at end of file
++end
+diff --git a/test/spec_multipart.rb b/test/spec_multipart.rb
+index b0bf57c..e4e5981 100644
+--- a/test/spec_multipart.rb
++++ b/test/spec_multipart.rb
+@@ -48,6 +48,27 @@ describe Rack::Multipart do
+     params['profile']['bio'].should.include 'hello'
+   end
+
++  should "parse very long unquoted multipart file names" do
++    data = <<-EOF
++--AaB03x\r
++Content-Type: text/plain\r
++Content-Disposition: attachment; name=file; filename=#{'long' * 100}\r
++\r
++contents\r
++--AaB03x--\r
++    EOF
++
++    options = {
++      "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
++      "CONTENT_LENGTH" => data.length.to_s,
++      :input => StringIO.new(data)
++    }
++    env = Rack::MockRequest.env_for("/", options)
++    params = Rack::Utils::Multipart.parse_multipart(env)
++
++    params["file"][:filename].should.equal('long' * 100)
++  end
++
+   should "parse multipart upload with text file" do
+     env = Rack::MockRequest.env_for("/", multipart_fixture(:text))
+     params = Rack::Multipart.parse_multipart(env)
diff -Nru 
ruby-rack-1.4.1/debian/patches/0002-multipart-parser-avoid-unbounded-gets-method.patch
 
ruby-rack-1.4.1/debian/patches/0002-multipart-parser-avoid-unbounded-gets-method.patch
--- 
ruby-rack-1.4.1/debian/patches/0002-multipart-parser-avoid-unbounded-gets-method.patch
      1970-01-01 09:00:00.000000000 +0900
+++ 
ruby-rack-1.4.1/debian/patches/0002-multipart-parser-avoid-unbounded-gets-method.patch
      2013-02-10 23:07:16.000000000 +0900
@@ -0,0 +1,104 @@
+From: Eric Wong <normalper...@yhbt.net>
+Date: Wed, 22 Aug 2012 22:48:23 +0000
+Subject: multipart/parser: avoid unbounded #gets method
+
+Malicious clients may send excessively long lines
+to trigger out-of-memory errors in a Rack web server.
+
+Origin: upstream, 
https://github.com/rack/rack/commit/f95113402b7239f225282806673e1b6424522b18
+Bug: https://security-tracker.debian.org/tracker/CVE-2013-0183
+Bug-Debian: http://bugs.debian.org/698440
+
+---
+ lib/rack/multipart/parser.rb |   13 ++++++++---
+ test/spec_multipart.rb       |   53 ++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 63 insertions(+), 3 deletions(-)
+
+diff --git a/lib/rack/multipart/parser.rb b/lib/rack/multipart/parser.rb
+index 98eceaa..3773de7 100644
+--- a/lib/rack/multipart/parser.rb
++++ b/lib/rack/multipart/parser.rb
+@@ -68,9 +68,16 @@ module Rack
+
+       def fast_forward_to_first_boundary
+         loop do
+-          read_buffer = @io.gets
+-          break if read_buffer == full_boundary
+-          raise EOFError, "bad content body" if read_buffer.nil?
++          content = @io.read(BUFSIZE)
++          raise EOFError, "bad content body" unless content
++          @buf << content
++
++          while @buf.gsub!(/\A([^\n]*\n)/, '')
++            read_buffer = $1
++            return if read_buffer == full_boundary
++          end
++
++          raise EOFError, "bad content body" if Utils.bytesize(@buf) >= 
BUFSIZE
+         end
+       end
+
+diff --git a/test/spec_multipart.rb b/test/spec_multipart.rb
+index e4e5981..1c50d9a 100644
+--- a/test/spec_multipart.rb
++++ b/test/spec_multipart.rb
+@@ -69,6 +69,59 @@ contents\r
+     params["file"][:filename].should.equal('long' * 100)
+   end
+
++  should "reject insanely long boundaries" do
++    # using a pipe since a tempfile can use up too much space
++    rd, wr = IO.pipe
++
++    # we only call rewind once at start, so make sure it succeeds
++    # and doesn't hit ESPIPE
++    def rd.rewind; end
++    wr.sync = true
++
++    # mock out length to make this pipe look like a Tempfile
++    def rd.length
++      1024 * 1024 * 8
++    end
++
++    # write to a pipe in a background thread, this will write a lot
++    # unless Rack (properly) shuts down the read end
++    thr = Thread.new do
++      begin
++        wr.write("--AaB03x")
++
++        # make the initial boundary a few gigs long
++        longer = "0123456789" * 1024 * 1024
++        (1024 * 1024).times { wr.write(longer) }
++
++        wr.write("\r\n")
++        wr.write('Content-Disposition: form-data; name="a"; filename="a.txt"')
++        wr.write("\r\n")
++        wr.write("Content-Type: text/plain\r\n")
++        wr.write("\r\na")
++        wr.write("--AaB03x--\r\n")
++        wr.close
++      rescue => err # this is EPIPE if Rack shuts us down
++        err
++      end
++    end
++
++    fixture = {
++      "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
++      "CONTENT_LENGTH" => rd.length.to_s,
++      :input => rd,
++    }
++
++    env = Rack::MockRequest.env_for '/', fixture
++    lambda {
++      Rack::Multipart.parse_multipart(env)
++    }.should.raise(EOFError)
++    rd.close
++
++    err = thr.value
++    err.should.be.instance_of Errno::EPIPE
++    wr.close
++  end
++
+   should "parse multipart upload with text file" do
+     env = Rack::MockRequest.env_for("/", multipart_fixture(:text))
+     params = Rack::Multipart.parse_multipart(env)
diff -Nru ruby-rack-1.4.1/debian/patches/0003-Reimplement-auth-scheme-fix.patch 
ruby-rack-1.4.1/debian/patches/0003-Reimplement-auth-scheme-fix.patch
--- ruby-rack-1.4.1/debian/patches/0003-Reimplement-auth-scheme-fix.patch       
1970-01-01 09:00:00.000000000 +0900
+++ ruby-rack-1.4.1/debian/patches/0003-Reimplement-auth-scheme-fix.patch       
2013-02-11 11:20:43.000000000 +0900
@@ -0,0 +1,131 @@
+From: James Tucker <jftuc...@gmail.com>
+Date: Sun, 13 Jan 2013 13:10:20 -0800
+Subject: Reimplement auth scheme fix
+
+ * Add Rack::Auth.add_scheme to enable folks to fix anything that breaks
+ * Add common auth schemes, MS ones, AWS ones, etc are missing, as unlikely
+ * Checked Rails - they don't use our authorization code
+ * Checked Warden - uses rails
+ * Checked Omniauth - uses rails
+ * Checked doorkeeper - users rails
+ * Checked rack-authentication - does it's own thing
+ * Checked warden-oauth - doesn't do headers
+ * Checked devise - uses rails
+ * Checked oauth2-rack - header creation only
+ * Checked rack-oauth2-server - does it's own thing
+ * Probably missed a bunch, but that'll have to do
+
+Origin: upstream, 
https://github.com/rack/rack/commit/87df8796a6e4555ec8fd3817c419c6b44b7ca459
+Bug: https://security-tracker.debian.org/tracker/CVE-2013-0184
+Bug-Debian: http://bugs.debian.org/698440
+
+---
+ lib/rack.rb                       |   12 ++++++++
+ lib/rack/auth/abstract/request.rb |    6 +++-
+ test/spec_auth.rb                 |   57 +++++++++++++++++++++++++++++++++++++
+ 3 files changed, 74 insertions(+), 1 deletion(-)
+ create mode 100644 test/spec_auth.rb
+
+diff --git a/lib/rack.rb b/lib/rack.rb
+index acfcb5a..18d5097 100644
+--- a/lib/rack.rb
++++ b/lib/rack.rb
+@@ -73,6 +73,18 @@ module Rack
+       autoload :Params, "rack/auth/digest/params"
+       autoload :Request, "rack/auth/digest/request"
+     end
++
++    # Not all of the following schemes are "standards", but they are used 
often.
++    @schemes = %w[basic digest bearer mac token oauth oauth2]
++
++    def self.add_scheme scheme
++      @schemes << scheme
++      @schemes.uniq!
++    end
++
++    def self.schemes
++      @schemes.dup
++    end
+   end
+
+   module Session
+diff --git a/lib/rack/auth/abstract/request.rb 
b/lib/rack/auth/abstract/request.rb
+index 9e15c72..c1553bf 100644
+--- a/lib/rack/auth/abstract/request.rb
++++ b/lib/rack/auth/abstract/request.rb
+@@ -21,7 +21,11 @@ module Rack
+       end
+
+       def scheme
+-        @scheme ||= parts.first.downcase.to_sym
++        @scheme ||=
++          begin
++            s = parts.first.downcase
++            Rack::Auth.schemes.include?(s) ? s.to_sym : s
++          end
+       end
+
+       def params
+diff --git a/test/spec_auth.rb b/test/spec_auth.rb
+new file mode 100644
+index 0000000..6588bd1
+--- /dev/null
++++ b/test/spec_auth.rb
+@@ -0,0 +1,57 @@
++require 'rack'
++
++describe Rack::Auth do
++  it "should have all common authentication schemes" do
++    Rack::Auth.schemes.should.include? 'basic'
++    Rack::Auth.schemes.should.include? 'digest'
++    Rack::Auth.schemes.should.include? 'bearer'
++    Rack::Auth.schemes.should.include? 'token'
++  end
++
++  it "should allow registration of new auth schemes" do
++    Rack::Auth.schemes.should.not.include "test"
++    Rack::Auth.add_scheme "test"
++    Rack::Auth.schemes.should.include "test"
++  end
++end
++
++describe Rack::Auth::AbstractRequest do
++  it "should symbolize known auth schemes" do
++    env = Rack::MockRequest.env_for('/')
++    env['HTTP_AUTHORIZATION'] = 'Basic aXJyZXNwb25zaWJsZQ=='
++    req = Rack::Auth::AbstractRequest.new(env)
++    req.scheme.should == :basic
++
++
++    env['HTTP_AUTHORIZATION'] = 'Digest aXJyZXNwb25zaWJsZQ=='
++    req = Rack::Auth::AbstractRequest.new(env)
++    req.scheme.should == :digest
++
++    env['HTTP_AUTHORIZATION'] = 'Bearer aXJyZXNwb25zaWJsZQ=='
++    req = Rack::Auth::AbstractRequest.new(env)
++    req.scheme.should == :bearer
++
++    env['HTTP_AUTHORIZATION'] = 'MAC aXJyZXNwb25zaWJsZQ=='
++    req = Rack::Auth::AbstractRequest.new(env)
++    req.scheme.should == :mac
++
++    env['HTTP_AUTHORIZATION'] = 'Token aXJyZXNwb25zaWJsZQ=='
++    req = Rack::Auth::AbstractRequest.new(env)
++    req.scheme.should == :token
++
++    env['HTTP_AUTHORIZATION'] = 'OAuth aXJyZXNwb25zaWJsZQ=='
++    req = Rack::Auth::AbstractRequest.new(env)
++    req.scheme.should == :oauth
++
++    env['HTTP_AUTHORIZATION'] = 'OAuth2 aXJyZXNwb25zaWJsZQ=='
++    req = Rack::Auth::AbstractRequest.new(env)
++    req.scheme.should == :oauth2
++  end
++
++  it "should not symbolize unknown auth schemes" do
++    env = Rack::MockRequest.env_for('/')
++    env['HTTP_AUTHORIZATION'] = 'magic aXJyZXNwb25zaWJsZQ=='
++    req = Rack::Auth::AbstractRequest.new(env)
++    req.scheme.should == "magic"
++  end
++end
diff -Nru 
ruby-rack-1.4.1/debian/patches/0004-Prevent-symlink-path-traversals.patch 
ruby-rack-1.4.1/debian/patches/0004-Prevent-symlink-path-traversals.patch
--- ruby-rack-1.4.1/debian/patches/0004-Prevent-symlink-path-traversals.patch   
1970-01-01 09:00:00.000000000 +0900
+++ ruby-rack-1.4.1/debian/patches/0004-Prevent-symlink-path-traversals.patch   
2013-02-20 21:41:42.000000000 +0900
@@ -0,0 +1,40 @@
+Description: Prevent symlink path traversals
+ rack/file.rb (Rack::File) in Rack 1.5.x before 1.5.2 and 1.4.x before 1.4.5
+ allows attackers to access arbitrary files outside the intended root
+ directory via a crafted PATH_INFO environment variable, probably a directory
+ traversal vulnerability that is remotely exploitable, aka "symlink path 
traversals."
+
+Origin: upstream, 
https://github.com/rack/rack/commit/6f237e4c9fab649d3750482514f0fde76c56ab30
+Bug: https://security-tracker.debian.org/tracker/CVE-2013-0262
+Bug-Debian: http://bugs.debian.org/700173
+
+Index: ruby-rack/lib/rack/file.rb
+===================================================================
+--- ruby-rack.orig/lib/rack/file.rb    2013-02-20 21:36:40.000000000 +0900
++++ ruby-rack/lib/rack/file.rb 2013-02-20 21:39:58.265999186 +0900
+@@ -40,19 +40,14 @@
+       @path_info = Utils.unescape(env["PATH_INFO"])
+       parts = @path_info.split SEPS
+ 
+-      parts.inject(0) do |depth, part|
+-        case part
+-        when '', '.'
+-          depth
+-        when '..'
+-          return fail(404, "Not Found") if depth - 1 < 0
+-          depth - 1
+-        else
+-          depth + 1
+-        end
++      clean = []
++
++      parts.each do |part|
++        next if part.empty? || part == '.'
++        part == '..' ? clean.pop : clean << part
+       end
+ 
+-      @path = F.join(@root, *parts)
++      @path = F.join(@root, *clean)
+ 
+       available = begin
+         F.file?(@path) && F.readable?(@path)
diff -Nru 
ruby-rack-1.4.1/debian/patches/0005-Use-secure_compare-for-hmac-comparison.patch
 
ruby-rack-1.4.1/debian/patches/0005-Use-secure_compare-for-hmac-comparison.patch
--- 
ruby-rack-1.4.1/debian/patches/0005-Use-secure_compare-for-hmac-comparison.patch
    1970-01-01 09:00:00.000000000 +0900
+++ 
ruby-rack-1.4.1/debian/patches/0005-Use-secure_compare-for-hmac-comparison.patch
    2013-02-20 23:15:59.000000000 +0900
@@ -0,0 +1,65 @@
+Description: Use secure compare for hmac comparison
+ Rack::Session::Cookie in Rack 1.5.x before 1.5.2, 1.4.x before 1.4.5,
+ 1.3.x before 1.3.10, 1.2.x before 1.2.8, and 1.1.x before 1.1.6 allows
+ remote attackers to guess the session cookie, gain privileges, and
+ execute arbitrary code via a timing attack involving am HMAC
+ comparison function that does not run in constant time.
+
+Origin: upstream,
+ https://github.com/rack/rack/commit/0cd7e9aa397f8ebb3b8481d67dbac8b4863a7f07,
+ https://github.com/rack/rack/commit/9a81b961457805f6d1a5c275d053068440421e11
+Bug: https://security-tracker.debian.org/tracker/CVE-2013-0263
+Bug-Debian: http://bugs.debian.org/700226
+
+Index: ruby-rack/lib/rack/session/cookie.rb
+===================================================================
+--- ruby-rack.orig/lib/rack/session/cookie.rb  2013-02-11 15:09:25.000000000 
+0900
++++ ruby-rack/lib/rack/session/cookie.rb       2013-02-20 23:11:19.091085974 
+0900
+@@ -108,7 +108,7 @@
+ 
+             if session_data && digest
+               ok = @secrets.any? do |secret|
+-                secret && digest == generate_hmac(session_data, secret)
++                secret && Rack::Utils.secure_compare(digest, 
generate_hmac(session_data, secret))
+               end
+             end
+ 
+Index: ruby-rack/lib/rack/utils.rb
+===================================================================
+--- ruby-rack.orig/lib/rack/utils.rb   2013-02-11 15:09:25.000000000 +0900
++++ ruby-rack/lib/rack/utils.rb        2013-02-20 23:12:39.171087876 +0900
+@@ -336,6 +336,18 @@
+     end
+     module_function :byte_ranges
+ 
++    # Constant time string comparison.
++    def secure_compare(a, b)
++      return false unless bytesize(a) == bytesize(b)
++
++      l = a.unpack("C*")
++
++      r, i = 0, -1
++      b.each_byte { |v| r |= v ^ l[i+=1] }
++      r == 0
++    end
++    module_function :secure_compare
++
+     # Context allows the use of a compatible middleware at different points
+     # in a request handling stack. A compatible middleware must define
+     # #context which should take the arguments env and app. The first of which
+Index: ruby-rack/test/spec_utils.rb
+===================================================================
+--- ruby-rack.orig/test/spec_utils.rb  2013-02-11 15:09:25.000000000 +0900
++++ ruby-rack/test/spec_utils.rb       2013-02-20 23:13:55.627089693 +0900
+@@ -322,6 +322,11 @@
+     Rack::Utils.bytesize("FOO\xE2\x82\xAC").should.equal 6
+   end
+ 
++  should "should perform constant time string comparison" do
++    Rack::Utils.secure_compare('a', 'a').should.equal true
++    Rack::Utils.secure_compare('a', 'b').should.equal false
++  end
++
+   should "return status code for integer" do
+     Rack::Utils.status_code(200).should.equal 200
+   end
diff -Nru ruby-rack-1.4.1/debian/patches/series 
ruby-rack-1.4.1/debian/patches/series
--- ruby-rack-1.4.1/debian/patches/series       1970-01-01 09:00:00.000000000 
+0900
+++ ruby-rack-1.4.1/debian/patches/series       2013-02-21 21:10:07.000000000 
+0900
@@ -0,0 +1,5 @@
+0001-Fix-parsing-performance-for-unquoted-filenames.patch
+0002-multipart-parser-avoid-unbounded-gets-method.patch
+0003-Reimplement-auth-scheme-fix.patch
+0004-Prevent-symlink-path-traversals.patch
+0005-Use-secure_compare-for-hmac-comparison.patch

unblock ruby-rack/1.4.1-2.1

-- System Information:
Debian Release: 7.0
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing')
Architecture: amd64 (x86_64)

Kernel: Linux 3.2.0-4-amd64 (SMP w/4 CPU cores)
Locale: LANG=ja_JP.UTF-8, LC_CTYPE=ja_JP.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash


-- 
To UNSUBSCRIBE, email to debian-release-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: 
http://lists.debian.org/20130221143142.24315.29364.report...@dandelion.in.yoikaze.org

Reply via email to