RubyGems is the typical packaging tool for ruby packages.
RubyGems home page:
http://rubygems.org/
Ruby home page:
http://ruby-lang.org
Problem Description:
RubyGems does not check installation paths for gems before writing
files.
Impact:
Since RubyGems packages are typically installed using root
permissions, arbitrary files may be overwritten on-disk. This may
lead to denial of service, privilege escalation or remote compromise.
Workaround:
No known workarounds
Solution:
a) Upgrade to RubyGems 0.9.1
b) Apply one of the following patches
For RubyGems 0.9.0:
Index: lib/rubygems/installer.rb
===================================================================
--- lib/rubygems/installer.rb (revision 1195)
+++ lib/rubygems/installer.rb (working copy)
@@ -335,14 +335,20 @@ TEXT
#
def extract_files(directory, format)
require 'fileutils'
- wd = Dir.getwd
- Dir.chdir directory do
- format.file_entries.each do |entry, file_data|
- path = entry['path'].untaint
- FileUtils.mkdir_p File.dirname(path)
- File.open(path, "wb") do |out|
- out.write file_data
- end
+ format.file_entries.each do |entry, file_data|
+ path = entry['path'].untaint
+ if path =~ /\A\// then # for extra sanity
+ raise Gem::InstallError,
+ "attempt to install file into #{entry['path'].inspect}"
+ end
+ path = File.expand_path File.join(directory, path)
+ if path !~ /\A#{Regexp.escape directory}/ then
+ raise Gem::InstallError,
+ "attempt to install file into #{entry['path'].inspect}"
+ end
+ FileUtils.mkdir_p File.dirname(path)
+ File.open(path, "wb") do |out|
+ out.write file_data
end
end
end
Remote installations via Rubyforge will be disabled in the near
future for versions of RubyGems earlier than 0.9.1, even for patched
versions of RubyGems. Local installations will continue to work,
however.
Thanks to Gavin Sinclair for finding and reporting this problem.
Testing your updated RubyGems:
Installing rspec-0.7.5 will give an InstallError on a patched version
of RubyGems:
$ gem install rspec --version 0.7.5
ERROR: While executing gem ... (Gem::InstallError)
attempt to install file into "../web_spec/
web_test_html_formatter.rb"
An updated rspec (0.7.5.1) has already been released.
--
Eric Hodel - drbrain (at) segment7 (dot) net [email concealed] - http://blog.segment7.net
RubyGems is the typical packaging tool for ruby packages.
RubyGems home page:
http://rubygems.org/
Ruby home page:
http://ruby-lang.org
Problem Description:
RubyGems does not check installation paths for gems before writing
files.
Impact:
Since RubyGems packages are typically installed using root
permissions, arbitrary files may be overwritten on-disk. This may
lead to denial of service, privilege escalation or remote compromise.
Workaround:
No known workarounds
Solution:
a) Upgrade to RubyGems 0.9.1
b) Apply one of the following patches
For RubyGems 0.9.0:
Index: lib/rubygems/installer.rb
===================================================================
--- lib/rubygems/installer.rb (revision 1195)
+++ lib/rubygems/installer.rb (working copy)
@@ -335,14 +335,20 @@ TEXT
#
def extract_files(directory, format)
require 'fileutils'
- wd = Dir.getwd
- Dir.chdir directory do
- format.file_entries.each do |entry, file_data|
- path = entry['path'].untaint
- FileUtils.mkdir_p File.dirname(path)
- File.open(path, "wb") do |out|
- out.write file_data
- end
+ format.file_entries.each do |entry, file_data|
+ path = entry['path'].untaint
+ if path =~ /\A\// then # for extra sanity
+ raise Gem::InstallError,
+ "attempt to install file into #{entry['path'].inspect}"
+ end
+ path = File.expand_path File.join(directory, path)
+ if path !~ /\A#{Regexp.escape directory}/ then
+ raise Gem::InstallError,
+ "attempt to install file into #{entry['path'].inspect}"
+ end
+ FileUtils.mkdir_p File.dirname(path)
+ File.open(path, "wb") do |out|
+ out.write file_data
end
end
end
For RubyGems 0.8.11:
Index: lib/rubygems/installer.rb
===================================================================
--- lib/rubygems/installer.rb (revision 1195)
+++ lib/rubygems/installer.rb (working copy)
@@ -7,6 +7,8 @@ require 'rubygems/dependency_list'
module Gem
+ class InstallError < Gem::Exception; end
+
class DependencyRemovalException < Gem::Exception; end
##
@@ -321,14 +323,20 @@ TEXT
#
def extract_files(directory, format)
require 'fileutils'
- wd = Dir.getwd
- Dir.chdir directory do
- format.file_entries.each do |entry, file_data|
- path = entry['path']
- FileUtils.mkdir_p File.dirname(path)
- File.open(path, "wb") do |out|
- out.write file_data
- end
+ format.file_entries.each do |entry, file_data|
+ path = entry['path']
+ if path =~ /\A\// then # for extra sanity
+ raise Gem::InstallError,
+ "attempt to install file into #{entry['path'].inspect}"
+ end
+ path = File.expand_path File.join(directory, path)
+ if path !~ /\A#{Regexp.escape directory}/ then
+ raise Gem::InstallError,
+ "attempt to install file into #{entry['path'].inspect}"
+ end
+ FileUtils.mkdir_p File.dirname(path)
+ File.open(path, "wb") do |out|
+ out.write file_data
end
end
end
MD5 (installer.rb.extract_files.REL_0_8_11.patch) =
31e3bacd1821de0272864c153b7c0dca
MD5 (installer.rb.extract_files.REL_0_9_0.patch) =
bed4fcdd438a7d8b81cf72e1ffe48a7d
Patches may also be downloaded here:
http://rubyforge.org/frs/shownotes.php?group_id=126&release_id=9074
Note:
Remote installations via Rubyforge will be disabled in the near
future for versions of RubyGems earlier than 0.9.1, even for patched
versions of RubyGems. Local installations will continue to work,
however.
Thanks to Gavin Sinclair for finding and reporting this problem.
Testing your updated RubyGems:
Installing rspec-0.7.5 will give an InstallError on a patched version
of RubyGems:
$ gem install rspec --version 0.7.5
ERROR: While executing gem ... (Gem::InstallError)
attempt to install file into "../web_spec/
web_test_html_formatter.rb"
An updated rspec (0.7.5.1) has already been released.
--
Eric Hodel - drbrain (at) segment7 (dot) net [email concealed] - http://blog.segment7.net
I LIT YOUR GEM ON FIRE!
[ reply ]