[rubygem-actionpack/f21] Fix CVE-2014-7818 (rhbz#1163511) and CVE-2014-7829 (rhbz#1165077)

Josef Stribny jstribny at fedoraproject.org
Tue Nov 18 10:52:26 UTC 2014


commit b7a53b1bccedc0094e0b49d04a78422922c930dd
Author: Josef Stribny <jstribny at redhat.com>
Date:   Tue Nov 18 11:52:11 2014 +0100

    Fix CVE-2014-7818 (rhbz#1163511) and CVE-2014-7829 (rhbz#1165077)

 rubygem-actionpack-4.1.7-CVE-2014-7818.patch |  100 ++++++++++++++++++++++++++
 rubygem-actionpack-4.1.8-CVE-2014-7829.patch |   96 ++++++++++++++++++++++++
 rubygem-actionpack.spec                      |   15 ++++-
 3 files changed, 210 insertions(+), 1 deletions(-)
---
diff --git a/rubygem-actionpack-4.1.7-CVE-2014-7818.patch b/rubygem-actionpack-4.1.7-CVE-2014-7818.patch
new file mode 100644
index 0000000..17b79eb
--- /dev/null
+++ b/rubygem-actionpack-4.1.7-CVE-2014-7818.patch
@@ -0,0 +1,100 @@
+From: Aaron Patterson <aaron.patterson at gmail.com>
+Date: Fri, 10 Oct 2014 16:00:03 -0700
+Subject: [PATCH] FileHandler should not be called for files outside the root
+
+FileHandler#matches? should return false for files that are outside the
+"root" path.
+
+Conflicts:
+        actionpack/lib/action_dispatch/middleware/static.rb
+---
+ .../lib/action_dispatch/middleware/static.rb       | 22 +++++++++++++++++++++-
+ actionpack/test/dispatch/static_test.rb            | 22 ++++++++++++++++++++--
+ 2 files changed, 41 insertions(+), 3 deletions(-)
+
+diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb
+index 2764584..df77021 100644
+--- a/lib/action_dispatch/middleware/static.rb
++++ b/lib/action_dispatch/middleware/static.rb
+@@ -14,7 +14,8 @@ module ActionDispatch
+       path = unescape_path(path)
+       return false unless path.valid_encoding?
+ 
+-      full_path = path.empty? ? @root : File.join(@root, escape_glob_chars(path))
++      full_path = path.empty? ? @root : File.join(@root,
++        clean_path_info(escape_glob_chars(path)))
+       paths = "#{full_path}#{ext}"
+ 
+       matches = Dir[paths]
+@@ -43,6 +44,25 @@ module ActionDispatch
+     def escape_glob_chars(path)
+       path.gsub(/[*?{}\[\]]/, "\\\\\\&")
+     end
++
++    private
++
++    PATH_SEPS = Regexp.union(*[::File::SEPARATOR, ::File::ALT_SEPARATOR].compact)
++
++    def clean_path_info(path_info)
++      parts = path_info.split PATH_SEPS
++
++      clean = []
++
++      parts.each do |part|
++        next if part.empty? || part == '.'
++        part == '..' ? clean.pop : clean << part
++      end
++
++      clean.unshift '/' if parts.empty? || parts.first.empty?
++
++      ::File.join(*clean)
++    end
+   end
+ 
+   class Static
+diff --git a/actionpack/test/dispatch/static_test.rb b/actionpack/test/dispatch/static_test.rb
+index afdda70..4e9cdc3 100644
+--- a/test/dispatch/static_test.rb
++++ b/test/dispatch/static_test.rb
+@@ -154,7 +154,8 @@ class StaticTest < ActiveSupport::TestCase
+   }
+ 
+   def setup
+-    @app = ActionDispatch::Static.new(DummyApp, "#{FIXTURE_LOAD_PATH}/public", "public, max-age=60")
++    @root = "#{FIXTURE_LOAD_PATH}/public"
++    @app = ActionDispatch::Static.new(DummyApp, @root, "public, max-age=60")
+   end
+ 
+   def public_path
+@@ -162,11 +163,28 @@ class StaticTest < ActiveSupport::TestCase
+   end
+ 
+   include StaticTests
++
++  def test_custom_handler_called_when_file_is_outside_root
++    filename = 'shared.html.erb'
++    assert File.exist?(File.join(@root, '..', filename))
++    env = {
++      "REQUEST_METHOD"=>"GET",
++      "REQUEST_PATH"=>"/..%2F#{filename}",
++      "PATH_INFO"=>"/..%2F#{filename}",
++      "REQUEST_URI"=>"/..%2F#{filename}",
++      "HTTP_VERSION"=>"HTTP/1.1",
++      "SERVER_NAME"=>"localhost",
++      "SERVER_PORT"=>"8080",
++      "QUERY_STRING"=>""
++    }
++    assert_equal(DummyApp.call(nil), @app.call(env))
++  end
+ end
+ 
+ class StaticEncodingTest < StaticTest
+   def setup
+-    @app = ActionDispatch::Static.new(DummyApp, "#{FIXTURE_LOAD_PATH}/公共", "public, max-age=60")
++    @root = "#{FIXTURE_LOAD_PATH}/公共"
++    @app = ActionDispatch::Static.new(DummyApp, @root, "public, max-age=60")
+   end
+ 
+   def public_path
+-- 
+1.9.3 (Apple Git-50)
diff --git a/rubygem-actionpack-4.1.8-CVE-2014-7829.patch b/rubygem-actionpack-4.1.8-CVE-2014-7829.patch
new file mode 100644
index 0000000..886dcc4
--- /dev/null
+++ b/rubygem-actionpack-4.1.8-CVE-2014-7829.patch
@@ -0,0 +1,96 @@
+From: Aaron Patterson <aaron.patterson at gmail.com>
+Date: Wed, 5 Nov 2014 15:37:36 -0800
+Subject: [PATCH] correctly escape backslashes in request path globs
+
+make sure that unreadable files are also not leaked
+
+CVE-2014-7829
+---
+ .../lib/action_dispatch/middleware/static.rb       |  4 +--
+ actionpack/test/dispatch/static_test.rb            | 41 ++++++++++++++++++++++
+ 2 files changed, 43 insertions(+), 2 deletions(-)
+
+diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb
+index df77021..2303447 100644
+--- a/lib/action_dispatch/middleware/static.rb
++++ b/lib/action_dispatch/middleware/static.rb
+@@ -19,7 +19,7 @@ module ActionDispatch
+       paths = "#{full_path}#{ext}"
+ 
+       matches = Dir[paths]
+-      match = matches.detect { |m| File.file?(m) }
++      match = matches.detect { |m| File.file?(m) && File.readable?(m) }
+       if match
+         match.sub!(@compiled_root, '')
+         ::Rack::Utils.escape(match)
+@@ -42,7 +42,7 @@ module ActionDispatch
+     end
+ 
+     def escape_glob_chars(path)
+-      path.gsub(/[*?{}\[\]]/, "\\\\\\&")
++      path.gsub(/[*?{}\[\]\\]/, "\\\\\\&")
+     end
+ 
+     private
+diff --git a/actionpack/test/dispatch/static_test.rb b/actionpack/test/dispatch/static_test.rb
+index 4e9cdc3..1039413 100644
+--- a/test/dispatch/static_test.rb
++++ b/test/dispatch/static_test.rb
+@@ -1,5 +1,6 @@
+ # encoding: utf-8
+ require 'abstract_unit'
++require 'fileutils'
+ require 'rbconfig'
+ 
+ module StaticTests
+@@ -164,6 +165,46 @@ class StaticTest < ActiveSupport::TestCase
+ 
+   include StaticTests
+ 
++  def test_custom_handler_called_when_file_is_not_readable
++    filename = 'unreadable.html.erb'
++    target = File.join(@root, filename)
++    FileUtils.touch target
++    File.chmod 0200, target
++    assert File.exist? target
++    assert !File.readable?(target)
++    path = "/#{filename}"
++    env = {
++      "REQUEST_METHOD"=>"GET",
++      "REQUEST_PATH"=> path,
++      "PATH_INFO"=> path,
++      "REQUEST_URI"=> path,
++      "HTTP_VERSION"=>"HTTP/1.1",
++      "SERVER_NAME"=>"localhost",
++      "SERVER_PORT"=>"8080",
++      "QUERY_STRING"=>""
++    }
++    assert_equal(DummyApp.call(nil), @app.call(env))
++  ensure
++    File.unlink target
++  end
++
++  def test_custom_handler_called_when_file_is_outside_root_backslash
++    filename = 'shared.html.erb'
++    assert File.exist?(File.join(@root, '..', filename))
++    path = "/%5C..%2F#{filename}"
++    env = {
++      "REQUEST_METHOD"=>"GET",
++      "REQUEST_PATH"=> path,
++      "PATH_INFO"=> path,
++      "REQUEST_URI"=> path,
++      "HTTP_VERSION"=>"HTTP/1.1",
++      "SERVER_NAME"=>"localhost",
++      "SERVER_PORT"=>"8080",
++      "QUERY_STRING"=>""
++    }
++    assert_equal(DummyApp.call(nil), @app.call(env))
++  end
++
+   def test_custom_handler_called_when_file_is_outside_root
+     filename = 'shared.html.erb'
+     assert File.exist?(File.join(@root, '..', filename))
+-- 
+1.9.3 (Apple Git-50)
+
+
diff --git a/rubygem-actionpack.spec b/rubygem-actionpack.spec
index 97197a5..bf302e3 100644
--- a/rubygem-actionpack.spec
+++ b/rubygem-actionpack.spec
@@ -5,7 +5,7 @@ Summary: Web-flow and rendering framework putting the VC in MVC
 Name: rubygem-%{gem_name}
 Epoch: 1
 Version: 4.1.5
-Release: 1%{?dist}
+Release: 2%{?dist}
 Group: Development/Languages
 License: MIT
 URL: http://www.rubyonrails.org
@@ -19,6 +19,11 @@ Source0: http://rubygems.org/downloads/actionpack-%{version}.gem
 # tar czvf actionpack-4.1.5-tests.tgz test/
 Source2: actionpack-%{version}-tests.tgz
 
+# CVE-2014-7818: FileHandler should not be called for files outside the root
+Patch0: rubygem-actionpack-4.1.7-CVE-2014-7818.patch
+# CVE-2014-7829: Correctly escape backslashes in request path globs
+Patch1: rubygem-actionpack-4.1.8-CVE-2014-7829.patch
+
 # Let's keep Requires and BuildRequires sorted alphabeticaly
 BuildRequires: rubygems-devel
 BuildRequires: rubygem(activemodel) = %{version}
@@ -61,6 +66,11 @@ Documentation for %{name}
 # move the tests into place
 tar xzvf %{SOURCE2} -C .%{gem_instdir}
 
+pushd .%{gem_instdir}
+%patch0 -p1
+%patch1 -p1
+popd
+
 # Remove backup files
 # No! these are needed for rake test
 # find ./%{gem_instdir} -type f -name "*~" -delete
@@ -128,6 +138,9 @@ popd
 %{gem_instdir}/test/
 
 %changelog
+* Tue Nov 18 2014 Josef Stribny <jstribny at redhat.com> - 1:4.1.5-2
+- Fix CVE-2014-7818 (rhbz#1163511) and CVE-2014-7829 (rhbz#1165077)
+
 * Mon Aug 25 2014 Josef Stribny <jstribny at redhat.com> - 1:4.1.5-1
 - Update to actionpack 4.1.5
 


More information about the scm-commits mailing list