safe_ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []