File tree 1 file changed +59
-0
lines changed
1 file changed +59
-0
lines changed Original file line number Diff line number Diff line change
1
+ # XXX: This is purely a monkey patch to close the exploit vector for now, a more
2
+ # permanent solution should be pushed upstream into rubygems.
3
+
4
+ require "rubygems"
5
+
6
+ # Assert we're using Psych
7
+ abort "Use Psych for YAML, install libyaml and reinstall ruby" unless YAML == Psych
8
+
9
+ module Psych
10
+ class ForbiddenClassException < Exception
11
+ end
12
+
13
+ module Visitors
14
+ class WhitelistedToRuby < ToRuby
15
+ WHITELIST = %w(
16
+ Gem::Dependency
17
+ Gem::Platform
18
+ Gem::Requirement
19
+ Gem::Specification
20
+ Gem::Version
21
+ Gem::Version::Requirement
22
+ )
23
+
24
+ private
25
+
26
+ def resolve_class klassname
27
+ raise ForbiddenClassException , "Forbidden class in YAML: #{ klassname } " unless WHITELIST . include? klassname
28
+ super klassname
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ module Gem
35
+ class Specification
36
+ def self . from_yaml input
37
+ input = normalize_yaml_input input
38
+ nodes = Psych . parse input
39
+ spec = Psych ::Visitors ::WhitelistedToRuby . new . accept nodes
40
+
41
+ if spec && spec . class == FalseClass then
42
+ raise Gem ::EndOfYAMLException
43
+ end
44
+
45
+ unless Gem ::Specification === spec then
46
+ raise Gem ::Exception , "YAML data doesn't evaluate to gem specification"
47
+ end
48
+
49
+ unless ( spec . instance_variables . include? '@specification_version' or
50
+ spec . instance_variables . include? :@specification_version ) and
51
+ spec . instance_variable_get :@specification_version
52
+ spec . instance_variable_set :@specification_version ,
53
+ NONEXISTENT_SPECIFICATION_VERSION
54
+ end
55
+
56
+ spec
57
+ end
58
+ end
59
+ end
You can’t perform that action at this time.
0 commit comments