Skip to content

Commit ad5c0a5

Browse files
committed
Validate specification names when installing
This prevents a malicious user from crafting a gem that could write to an arbitrary directory, outside of the gems directory, by using metacharacters such as `..`
1 parent 44cc27c commit ad5c0a5

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

lib/rubygems/installer.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,11 @@ def verify_gem_home(unpack = false) # :nodoc:
697697
unpack or File.writable?(gem_home)
698698
end
699699

700+
def verify_spec_name
701+
return if spec.name =~ Gem::Specification::VALID_NAME_PATTERN
702+
raise Gem::InstallError, "#{spec} has an invalid name"
703+
end
704+
700705
##
701706
# Return the text for an application file.
702707

@@ -823,6 +828,8 @@ def pre_install_checks
823828

824829
ensure_loadable_spec
825830

831+
verify_spec_name
832+
826833
if options[:install_as_default]
827834
Gem.ensure_default_gem_subdirectories gem_home
828835
else

test/rubygems/test_gem_installer.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,6 +1448,26 @@ def test_pre_install_checks_wrong_rubygems_version
14481448
end
14491449
end
14501450

1451+
def test_pre_install_checks_malicious_name
1452+
spec = util_spec '../malicious', '1'
1453+
def spec.full_name # so the spec is buildable
1454+
"malicious-1"
1455+
end
1456+
def spec.validate; end
1457+
1458+
util_build_gem spec
1459+
1460+
gem = File.join(@gemhome, 'cache', spec.file_name)
1461+
1462+
use_ui @ui do
1463+
@installer = Gem::Installer.at gem
1464+
e = assert_raises Gem::InstallError do
1465+
@installer.pre_install_checks
1466+
end
1467+
assert_equal '#<Gem::Specification name=../malicious version=1> has an invalid name', e.message
1468+
end
1469+
end
1470+
14511471
def test_shebang
14521472
util_make_exec @spec, "#!/usr/bin/ruby"
14531473

0 commit comments

Comments
 (0)