safe_ruby 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7d4ffe979b9bf21d82a84ddcde617929e662043a
4
+ data.tar.gz: 4e4df66000d092c3dbf313bb7466864e3fbb6b80
5
+ SHA512:
6
+ metadata.gz: 62d8d6995ba25aea59887d21b11ccc9dbd2429a930989cca4b04d854ad2271afbe0cb033e13c747a9222d43bc4773a0a1337fb8ec0b75311b28f9443ffdf4644
7
+ data.tar.gz: 45a67beadc6238612f86c4f99f49c160f7a0603687720c24b793d8ba9b5f22c85dfe0408b70199e43ea53024a3c10cf88e472b14fedf8d8a7f84f32e2ef0a344
@@ -0,0 +1,12 @@
1
+ ALLOWED_CONSTANTS=
2
+ [ :Object, :Module, :Class, :BasicObject, :Kernel, :NilClass, :NIL, :Data, :TrueClass, :TRUE, :FalseClass, :FALSE, :Encoding,
3
+ :Comparable, :Enumerable, :String, :Symbol, :Exception, :SystemExit, :SignalException, :Interrupt, :StandardError, :TypeError,
4
+ :ArgumentError, :IndexError, :KeyError, :RangeError, :ScriptError, :SyntaxError, :LoadError, :NotImplementedError, :NameError,
5
+ :NoMethodError, :RuntimeError, :SecurityError, :NoMemoryError, :EncodingError, :SystemCallError, :Errno, :ZeroDivisionError,
6
+ :FloatDomainError, :Numeric, :Integer, :Fixnum, :Float, :Bignum, :Array, :Hash, :Struct, :RegexpError, :Regexp,
7
+ :MatchData, :Marshal, :Range, :IOError, :EOFError, :IO, :STDIN, :STDOUT, :STDERR, :Time, :Random,
8
+ :Signal, :Proc, :LocalJumpError, :SystemStackError, :Method, :UnboundMethod, :Binding, :Math, :Enumerator,
9
+ :StopIteration, :RubyVM, :Thread, :TOPLEVEL_BINDING, :ThreadGroup, :Mutex, :ThreadError, :Fiber, :FiberError, :Rational, :Complex,
10
+ :RUBY_VERSION, :RUBY_RELEASE_DATE, :RUBY_PLATFORM, :RUBY_PATCHLEVEL, :RUBY_REVISION, :RUBY_DESCRIPTION, :RUBY_COPYRIGHT, :RUBY_ENGINE,
11
+ :TracePoint, :ARGV, :Gem, :RbConfig, :Config, :CROSS_COMPILING, :Date, :ConditionVariable, :Queue, :SizedQueue, :MonitorMixin, :Monitor,
12
+ :Exception2MessageMapper, :IRB, :RubyToken, :RubyLex, :Readline, :RUBYGEMS_ACTIVATION_MONITOR]
@@ -0,0 +1,51 @@
1
+ MAKE_SAFE_CODE = <<-STRING
2
+ def keep_singleton_methods(klass, singleton_methods)
3
+ klass = Object.const_get(klass)
4
+ singleton_methods = singleton_methods.map(&:to_sym)
5
+ undef_methods = (klass.singleton_methods - singleton_methods)
6
+
7
+ undef_methods.each do |method|
8
+ klass.singleton_class.send(:undef_method, method)
9
+ end
10
+
11
+ end
12
+
13
+ def keep_methods(klass, methods)
14
+ klass = Object.const_get(klass)
15
+ methods = methods.map(&:to_sym)
16
+ undef_methods = (klass.methods(false) - methods)
17
+ undef_methods.each do |method|
18
+ klass.send(:undef_method, method)
19
+ end
20
+ end
21
+
22
+ def clean_constants
23
+ (Object.constants - #{ALLOWED_CONSTANTS}).each do |const|
24
+ Object.send(:remove_const, const) if defined?(const)
25
+ end
26
+ end
27
+
28
+ keep_singleton_methods(:Kernel, #{KERNEL_S_METHODS})
29
+ keep_singleton_methods(:Symbol, #{SYMBOL_S_METHODS})
30
+ keep_singleton_methods(:String, #{STRING_S_METHODS})
31
+ keep_singleton_methods(:IO, #{IO_S_METHODS})
32
+
33
+ keep_methods(:Kernel, #{KERNEL_METHODS})
34
+ keep_methods(:NilClass, #{NILCLASS_METHODS})
35
+ keep_methods(:TrueClass, #{TRUECLASS_METHODS})
36
+ keep_methods(:FalseClass, #{FALSECLASS_METHODS})
37
+ keep_methods(:Enumerable, #{ENUMERABLE_METHODS})
38
+ keep_methods(:String, #{STRING_METHODS})
39
+ Kernel.class_eval do
40
+ def `(*args)
41
+ raise NoMethodError, "` is unavailable"
42
+ end
43
+
44
+ def system(*args)
45
+ raise NoMethodError, "system is unavailable"
46
+ end
47
+ end
48
+
49
+ clean_constants
50
+
51
+ STRING
@@ -0,0 +1,271 @@
1
+ IO_S_METHODS = %w[
2
+ new
3
+ foreach
4
+ open
5
+ ]
6
+
7
+ KERNEL_S_METHODS = %w[
8
+ Array
9
+ binding
10
+ block_given?
11
+ catch
12
+ chomp
13
+ chomp!
14
+ chop
15
+ chop!
16
+ eval
17
+ fail
18
+ Float
19
+ format
20
+ global_variables
21
+ gsub
22
+ gsub!
23
+ Integer
24
+ iterator?
25
+ lambda
26
+ local_variables
27
+ loop
28
+ method_missing
29
+ proc
30
+ raise
31
+ scan
32
+ split
33
+ sprintf
34
+ String
35
+ sub
36
+ sub!
37
+ throw
38
+ ].freeze
39
+
40
+ SYMBOL_S_METHODS = %w[
41
+ all_symbols
42
+ ].freeze
43
+
44
+ STRING_S_METHODS = %w[
45
+ new
46
+ ].freeze
47
+
48
+ KERNEL_METHODS = %w[
49
+ ==
50
+
51
+ ray
52
+ nding
53
+ ock_given?
54
+ tch
55
+ omp
56
+ omp!
57
+ op
58
+ op!
59
+ ass
60
+ clone
61
+ dup
62
+ eql?
63
+ equal?
64
+ eval
65
+ fail
66
+ Float
67
+ format
68
+ freeze
69
+ frozen?
70
+ global_variables
71
+ gsub
72
+ gsub!
73
+ hash
74
+ id
75
+ initialize_copy
76
+ inspect
77
+ instance_eval
78
+ instance_of?
79
+ instance_variables
80
+ instance_variable_get
81
+ instance_variable_set
82
+ instance_variable_defined?
83
+ Integer
84
+ is_a?
85
+ iterator?
86
+ kind_of?
87
+ lambda
88
+ local_variables
89
+ loop
90
+ methods
91
+ method_missing
92
+ nil?
93
+ private_methods
94
+ print
95
+ proc
96
+ protected_methods
97
+ public_methods
98
+ raise
99
+ remove_instance_variable
100
+ respond_to?
101
+ respond_to_missing?
102
+ scan
103
+ send
104
+ singleton_methods
105
+ singleton_method_added
106
+ singleton_method_removed
107
+ singleton_method_undefined
108
+ split
109
+ sprintf
110
+ String
111
+ sub
112
+ sub!
113
+ taint
114
+ tainted?
115
+ throw
116
+ to_a
117
+ to_s
118
+ type
119
+ untaint
120
+ __send__
121
+ ].freeze
122
+
123
+ NILCLASS_METHODS = %w[
124
+ &
125
+ inspect
126
+ nil?
127
+ to_a
128
+ to_f
129
+ to_i
130
+ to_s
131
+ ^
132
+ |
133
+ ].freeze
134
+
135
+ SYMBOL_METHODS = %w[
136
+ ===
137
+ id2name
138
+ inspect
139
+ to_i
140
+ to_int
141
+ to_s
142
+ to_sym
143
+ ].freeze
144
+
145
+ TRUECLASS_METHODS = %w[
146
+ &
147
+ to_s
148
+ ^
149
+ |
150
+ ].freeze
151
+
152
+ FALSECLASS_METHODS = %w[
153
+ &
154
+ to_s
155
+ ^
156
+ |
157
+ ].freeze
158
+
159
+ ENUMERABLE_METHODS = %w[
160
+ all?
161
+ any?
162
+ collect
163
+ detect
164
+ each_with_index
165
+ entries
166
+ find
167
+ find_all
168
+ grep
169
+ include?
170
+ inject
171
+ map
172
+ max
173
+ member?
174
+ min
175
+ partition
176
+ reject
177
+ select
178
+ sort
179
+ sort_by
180
+ to_a
181
+ zip
182
+ ].freeze
183
+
184
+ STRING_METHODS = %w[
185
+ %
186
+ *
187
+ +
188
+ <<
189
+ <=>
190
+ ==
191
+ =~
192
+ capitalize
193
+ capitalize!
194
+ casecmp
195
+ center
196
+ chomp
197
+ chomp!
198
+ chop
199
+ chop!
200
+ concat
201
+ count
202
+ crypt
203
+ delete
204
+ delete!
205
+ downcase
206
+ downcase!
207
+ dump
208
+ each
209
+ each_byte
210
+ each_line
211
+ empty?
212
+ eql?
213
+ gsub
214
+ gsub!
215
+ hash
216
+ hex
217
+ include?
218
+ index
219
+ initialize
220
+ initialize_copy
221
+ insert
222
+ inspect
223
+ intern
224
+ length
225
+ ljust
226
+ lines
227
+ lstrip
228
+ lstrip!
229
+ match
230
+ next
231
+ next!
232
+ oct
233
+ replace
234
+ reverse
235
+ reverse!
236
+ rindex
237
+ rjust
238
+ rstrip
239
+ rstrip!
240
+ scan
241
+ size
242
+ slice
243
+ slice!
244
+ split
245
+ squeeze
246
+ squeeze!
247
+ strip
248
+ strip!
249
+ start_with?
250
+ sub
251
+ sub!
252
+ succ
253
+ succ!
254
+ sum
255
+ swapcase
256
+ swapcase!
257
+ to_f
258
+ to_i
259
+ to_s
260
+ to_str
261
+ to_sym
262
+ tr
263
+ tr!
264
+ tr_s
265
+ tr_s!
266
+ upcase
267
+ upcase!
268
+ upto
269
+ []
270
+ []=
271
+ ].freeze
@@ -0,0 +1,9 @@
1
+ require 'childprocess'
2
+ require_relative 'method_whitelist'
3
+ require_relative 'constant_whitelist'
4
+ require_relative 'make_safe_code'
5
+ require_relative 'safe_ruby_runner'
6
+
7
+ class SafeRuby
8
+ VERSION = "0.0.0"
9
+ end
@@ -0,0 +1,46 @@
1
+ class SafeRuby
2
+ def initialize(code)
3
+ @code = code
4
+ end
5
+
6
+ def self.eval(code)
7
+ new(code).eval
8
+ end
9
+
10
+ def self.check(code, expected)
11
+ eval(code) == eval(expected)
12
+ end
13
+
14
+ def eval
15
+ temp = build_tempfile
16
+ read, write = IO.pipe
17
+ ChildProcess.build("ruby", temp.path).tap do |process|
18
+ process.io.stdout = write
19
+ process.io.stderr = write
20
+ process.start
21
+ process.wait
22
+ write.close
23
+ end
24
+
25
+ data = read.read
26
+ Marshal.load(data) rescue data
27
+ end
28
+
29
+ private
30
+
31
+ def build_tempfile
32
+ require 'tempfile'
33
+ file = Tempfile.new('saferuby')
34
+ file.write(MAKE_SAFE_CODE)
35
+ file.write <<-STRING
36
+ begin
37
+ result = eval('#{@code}')
38
+ puts Marshal.dump(result)
39
+ rescue => e
40
+ print e
41
+ end
42
+ STRING
43
+ file.rewind
44
+ file
45
+ end
46
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: safe_ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Uku Taht
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: childprocess
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.3.9
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.3.9
27
+ description: Whatever
28
+ email: uku.taht@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - lib/safe_ruby.rb
34
+ - lib/constant_whitelist.rb
35
+ - lib/make_safe_code.rb
36
+ - lib/method_whitelist.rb
37
+ - lib/safe_ruby_runner.rb
38
+ homepage: http://rubygems.org/gems/safe_ruby
39
+ licenses:
40
+ - MIT
41
+ metadata: {}
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubyforge_project:
58
+ rubygems_version: 2.1.11
59
+ signing_key:
60
+ specification_version: 4
61
+ summary: Run untrusted ruby code in a safe environment
62
+ test_files: []