mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
[rubygems/rubygems] Check requirements classes
Mitigate the security risk:
https://devcraft.io/2021/01/07/universal-deserialisation-gadget-for-ruby-2-x-3-x.html
141c2f4388
This commit is contained in:
parent
88e46cf6b8
commit
803c60858e
2 changed files with 36 additions and 0 deletions
|
@ -199,6 +199,8 @@ class Gem::Requirement
|
||||||
|
|
||||||
def marshal_load(array) # :nodoc:
|
def marshal_load(array) # :nodoc:
|
||||||
@requirements = array[0]
|
@requirements = array[0]
|
||||||
|
|
||||||
|
raise TypeError, "wrong @requirements" unless Array === @requirements
|
||||||
end
|
end
|
||||||
|
|
||||||
def yaml_initialize(tag, vals) # :nodoc:
|
def yaml_initialize(tag, vals) # :nodoc:
|
||||||
|
|
|
@ -422,6 +422,40 @@ class TestGemRequirement < Gem::TestCase
|
||||||
assert_requirement_hash_equal "1", "1.0.0"
|
assert_requirement_hash_equal "1", "1.0.0"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class Exploit < RuntimeError
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.exploit(arg)
|
||||||
|
raise Exploit, "arg = #{arg}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_marshal_load_attack
|
||||||
|
wa = Net::WriteAdapter.allocate
|
||||||
|
wa.instance_variable_set(:@socket, self.class)
|
||||||
|
wa.instance_variable_set(:@method_id, :exploit)
|
||||||
|
request_set = Gem::RequestSet.allocate
|
||||||
|
request_set.instance_variable_set(:@git_set, "id")
|
||||||
|
request_set.instance_variable_set(:@sets, wa)
|
||||||
|
wa = Net::WriteAdapter.allocate
|
||||||
|
wa.instance_variable_set(:@socket, request_set)
|
||||||
|
wa.instance_variable_set(:@method_id, :resolve)
|
||||||
|
ent = Gem::Package::TarReader::Entry.allocate
|
||||||
|
ent.instance_variable_set(:@read, 0)
|
||||||
|
ent.instance_variable_set(:@header, "aaa")
|
||||||
|
io = Net::BufferedIO.allocate
|
||||||
|
io.instance_variable_set(:@io, ent)
|
||||||
|
io.instance_variable_set(:@debug_output, wa)
|
||||||
|
reader = Gem::Package::TarReader.allocate
|
||||||
|
reader.instance_variable_set(:@io, io)
|
||||||
|
requirement = Gem::Requirement.allocate
|
||||||
|
requirement.instance_variable_set(:@requirements, reader)
|
||||||
|
m = [Gem::SpecFetcher, Gem::Installer, requirement]
|
||||||
|
e = assert_raise(TypeError) do
|
||||||
|
Marshal.load(Marshal.dump(m))
|
||||||
|
end
|
||||||
|
assert_equal(e.message, "wrong @requirements")
|
||||||
|
end
|
||||||
|
|
||||||
# Assert that two requirements are equal. Handles Gem::Requirements,
|
# Assert that two requirements are equal. Handles Gem::Requirements,
|
||||||
# strings, arrays, numbers, and versions.
|
# strings, arrays, numbers, and versions.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue