shikashi-the-north 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,331 @@
1
+ require "rubygems"
2
+ require "shikashi"
3
+
4
+ include Shikashi
5
+
6
+ $top_level_binding = binding
7
+
8
+ describe Sandbox, "Shikashi sandbox" do
9
+ it "should run empty code without privileges" do
10
+ Sandbox.new.run ""
11
+ end
12
+
13
+ it "should run empty code with privileges" do
14
+ Sandbox.new.run "", Privileges.new
15
+ end
16
+
17
+ class X
18
+ def foo
19
+ end
20
+ end
21
+ it "should raise SecurityError when call method without privileges" do
22
+
23
+ x = X.new
24
+
25
+ lambda {
26
+ Sandbox.new.run "x.foo", binding, :no_base_namespace => true
27
+ }.should raise_error(SecurityError)
28
+
29
+ end
30
+
31
+ it "should not raise anything when call method with privileges" do
32
+
33
+ x = X.new
34
+ privileges = Privileges.new
35
+ def privileges.allow?(*args)
36
+ true
37
+ end
38
+
39
+ Sandbox.new.run "x.foo", binding, :privileges => privileges, :no_base_namespace => true
40
+
41
+ end
42
+
43
+
44
+ module ::A4
45
+ module B4
46
+ module C4
47
+
48
+ end
49
+ end
50
+ end
51
+
52
+ it "should allow use a class declared inside" do
53
+ priv = Privileges.new
54
+ priv.allow_method :new
55
+ Sandbox.new.run("
56
+ class ::TestInsideClass
57
+ def foo
58
+ end
59
+ end
60
+
61
+ ::TestInsideClass.new.foo
62
+ ", priv)
63
+ end
64
+
65
+ it "should use base namespace when the code uses colon3 node (2 levels)" do
66
+ Sandbox.new.run( "::B4",
67
+ :base_namespace => A4
68
+ ).should be == A4::B4
69
+ end
70
+
71
+ it "should change base namespace when classes are declared (2 levels)" do
72
+ Sandbox.new.run( "
73
+ class ::X4
74
+ def foo
75
+ end
76
+ end
77
+ ",
78
+ :base_namespace => A4
79
+ )
80
+
81
+ A4::X4
82
+ end
83
+
84
+ it "should use base namespace when the code uses colon3 node (3 levels)" do
85
+ Sandbox.new.run( "::C4",
86
+ $top_level_binding, :base_namespace => ::A4::B4
87
+ ).should be == ::A4::B4::C4
88
+ end
89
+
90
+ it "should change base namespace when classes are declared (3 levels)" do
91
+ Sandbox.new.run( "
92
+ class ::X4
93
+ def foo
94
+ end
95
+ end
96
+ ",
97
+ $top_level_binding, :base_namespace => ::A4::B4
98
+ )
99
+
100
+ A4::B4::X4
101
+ end
102
+
103
+ it "should reach local variables when current binding is used" do
104
+ a = 5
105
+ Sandbox.new.run("a", binding, :no_base_namespace => true).should be == 5
106
+ end
107
+
108
+ class N
109
+ def foo
110
+ @a = 5
111
+ Sandbox.new.run("@a", binding, :no_base_namespace => true)
112
+ end
113
+ end
114
+
115
+
116
+ it "should allow reference to instance variables" do
117
+ N.new.foo.should be == 5
118
+ end
119
+
120
+ it "should create a default module for each sandbox" do
121
+ s = Sandbox.new
122
+ s.run('class X
123
+ def foo
124
+ "foo inside sandbox"
125
+ end
126
+ end')
127
+
128
+ x = s.base_namespace::X.new
129
+ x.foo.should be == "foo inside sandbox"
130
+ end
131
+
132
+ it "should not allow xstr when no authorized" do
133
+ s = Sandbox.new
134
+ priv = Privileges.new
135
+
136
+ lambda {
137
+ s.run("%x[echo hello world]", priv)
138
+ }.should raise_error(SecurityError)
139
+
140
+ end
141
+
142
+ it "should allow xstr when authorized" do
143
+ s = Sandbox.new
144
+ priv = Privileges.new
145
+
146
+ priv.allow_xstr
147
+
148
+ lambda {
149
+ s.run("%x[echo hello world]", priv)
150
+ }.should_not raise_error
151
+
152
+ end
153
+
154
+ it "should not allow global variable read" do
155
+ s = Sandbox.new
156
+ priv = Privileges.new
157
+
158
+ lambda {
159
+ s.run("$a", priv)
160
+ }.should raise_error(SecurityError)
161
+ end
162
+
163
+ it "should allow global variable read when authorized" do
164
+ s = Sandbox.new
165
+ priv = Privileges.new
166
+
167
+ priv.allow_global_read(:$a)
168
+
169
+ lambda {
170
+ s.run("$a", priv)
171
+ }.should_not raise_error
172
+ end
173
+
174
+ it "should not allow constant variable read" do
175
+ s = Sandbox.new
176
+ priv = Privileges.new
177
+
178
+ TESTCONSTANT9999 = 9999
179
+ lambda {
180
+ s.run("TESTCONSTANT9999", priv)
181
+ }.should raise_error(SecurityError)
182
+ end
183
+
184
+ it "should allow constant read when authorized" do
185
+ s = Sandbox.new
186
+ priv = Privileges.new
187
+
188
+ priv.allow_const_read("TESTCONSTANT9998")
189
+ ::TESTCONSTANT9998 = 9998
190
+
191
+ lambda {
192
+ s.run("TESTCONSTANT9998", priv).should be == 9998
193
+ }.should_not raise_error
194
+ end
195
+
196
+ it "should allow read constant nested on classes when authorized" do
197
+ s = Sandbox.new
198
+ priv = Privileges.new
199
+
200
+ priv.allow_const_read("Fixnum")
201
+ Fixnum::TESTCONSTANT9997 = 9997
202
+
203
+ lambda {
204
+ s.run("Fixnum::TESTCONSTANT9997", priv).should be == 9997
205
+ }.should_not raise_error
206
+ end
207
+
208
+
209
+ it "should not allow global variable write" do
210
+ s = Sandbox.new
211
+ priv = Privileges.new
212
+
213
+ lambda {
214
+ s.run("$a = 9", priv)
215
+ }.should raise_error(SecurityError)
216
+ end
217
+
218
+ it "should allow global variable write when authorized" do
219
+ s = Sandbox.new
220
+ priv = Privileges.new
221
+
222
+ priv.allow_global_write(:$a)
223
+
224
+ lambda {
225
+ s.run("$a = 9", priv)
226
+ }.should_not raise_error
227
+ end
228
+
229
+ it "should not allow constant write" do
230
+ s = Sandbox.new
231
+ priv = Privileges.new
232
+
233
+ lambda {
234
+ s.run("TESTCONSTANT9999 = 99991", priv)
235
+ }.should raise_error(SecurityError)
236
+ end
237
+
238
+ it "should allow constant write when authorized" do
239
+ s = Sandbox.new
240
+ priv = Privileges.new
241
+
242
+ priv.allow_const_write("TESTCONSTANT9998")
243
+
244
+ lambda {
245
+ s.run("TESTCONSTANT9998 = 99981", priv)
246
+ TESTCONSTANT9998.should be == 99981
247
+ }.should_not raise_error
248
+ end
249
+
250
+ it "should allow write constant nested on classes when authorized" do
251
+ s = Sandbox.new
252
+ priv = Privileges.new
253
+
254
+ priv.allow_const_read("Fixnum")
255
+ priv.allow_const_write("Fixnum::TESTCONSTANT9997")
256
+
257
+ lambda {
258
+ s.run("Fixnum::TESTCONSTANT9997 = 99971", priv)
259
+ Fixnum::TESTCONSTANT9997.should be == 99971
260
+ }.should_not raise_error
261
+ end
262
+
263
+ it "should allow package of code" do
264
+ s = Sandbox.new
265
+
266
+ lambda {
267
+ s.packet('print "hello world\n"')
268
+ }.should_not raise_error
269
+ end
270
+
271
+ def self.package_oracle(args1, args2)
272
+ it "should allow and execute package of code" do
273
+ e1 = nil
274
+ e2 = nil
275
+ r1 = nil
276
+ r2 = nil
277
+
278
+ begin
279
+ s = Sandbox.new
280
+ r1 = s.run(*(args1+args2))
281
+ rescue Exception => e
282
+ e1 = e
283
+ end
284
+
285
+ begin
286
+ s = Sandbox.new
287
+ packet = s.packet(*args1)
288
+ r2 = packet.run(*args2)
289
+ rescue Exception => e
290
+ e2 = e
291
+ end
292
+
293
+ e1.should be == e2
294
+ r1.should be == r2
295
+ end
296
+ end
297
+
298
+ class ::XPackage
299
+ def foo
300
+
301
+ end
302
+ end
303
+
304
+ package_oracle ["1"], [:binding => binding]
305
+ package_oracle ["1+1",{ :privileges => Privileges.allow_method(:+)}], [:binding => binding]
306
+
307
+ it "should accept references to classes defined on previous run" do
308
+ sandbox = Sandbox.new
309
+
310
+ sandbox.run("class XinsideSandbox
311
+ end")
312
+
313
+ sandbox.run("XinsideSandbox").should be == sandbox.base_namespace::XinsideSandbox
314
+ end
315
+
316
+ class OutsideX44
317
+ def method_missing(name)
318
+ name
319
+ end
320
+ end
321
+ OutsideX44_ins = OutsideX44.new
322
+
323
+ it "should allow method_missing handling" do
324
+ sandbox = Sandbox.new
325
+ privileges = Privileges.new
326
+ privileges.allow_const_read("OutsideX44_ins")
327
+ privileges.instances_of(OutsideX44).allow :method_missing
328
+
329
+ sandbox.run("OutsideX44_ins.foo", privileges).should be == :foo
330
+ end
331
+ end
@@ -0,0 +1,36 @@
1
+ require "shikashi"
2
+
3
+ include Shikashi
4
+
5
+ describe Sandbox, "Shikashi sandbox" do
6
+ it "should allow single run" do
7
+ Sandbox.run("0").should be == 0
8
+ end
9
+
10
+ it "should allow single run with empty privileges" do
11
+ priv = Privileges.new
12
+ Sandbox.run("0", priv).should be == 0
13
+ end
14
+
15
+ it "should allow single run with privileges allowing + method (as symbol)" do
16
+ priv = Privileges.new
17
+ priv.allow_method :+
18
+ Sandbox.run("1+1", priv).should be == 2
19
+ end
20
+
21
+ it "should allow single run with privileges allowing + method (as string)" do
22
+ priv = Privileges.new
23
+ priv.allow_method "+"
24
+ Sandbox.run("1+1", priv).should be == 2
25
+ end
26
+
27
+ it "should allow single run with privileges using sugar syntax and allowing + method (as symbol)" do
28
+ Sandbox.run("1+1", Privileges.allow_method(:+)).should be == 2
29
+ end
30
+
31
+ it "should allow single run with privileges using sugar syntax and allowing + method (as string)" do
32
+ Sandbox.run("1+1", Privileges.allow_method("+")).should be == 2
33
+ end
34
+
35
+ end
36
+
@@ -0,0 +1,59 @@
1
+ =begin
2
+
3
+ Authors:
4
+
5
+ Scott Ellard (scott.ellard@gmail.com)
6
+
7
+ This file is part of the shikashi project, http://github.com/tario/shikashi
8
+
9
+ Copyright (c) 2009-2010 Roberto Dario Seminara <robertodarioseminara@gmail.com>
10
+
11
+ shikashi is free software: you can redistribute it and/or modify
12
+ it under the terms of the gnu general public license as published by
13
+ the free software foundation, either version 3 of the license, or
14
+ (at your option) any later version.
15
+
16
+ shikashi is distributed in the hope that it will be useful,
17
+ but without any warranty; without even the implied warranty of
18
+ merchantability or fitness for a particular purpose. see the
19
+ gnu general public license for more details.
20
+
21
+ you should have received a copy of the gnu general public license
22
+ along with shikashi. if not, see <http://www.gnu.org/licenses/>.
23
+
24
+ =end
25
+ require "test/unit"
26
+ require "rubygems"
27
+ require "shikashi"
28
+
29
+ describe Shikashi::Sandbox, "Shikashi sandbox" do
30
+
31
+ it "should raise SecurityError when try to run shell cmd with backsticks" do
32
+ priv = Shikashi::Privileges.new
33
+ lambda {
34
+ Shikashi::Sandbox.new.run("`ls`", priv)
35
+ }.should raise_error(SecurityError)
36
+ end
37
+
38
+ it "should raise SecurityError when try to run shell cmd with percent" do
39
+ priv = Shikashi::Privileges.new
40
+ lambda {
41
+ Shikashi::Sandbox.new.run("%x[ls]", priv)
42
+ }.should raise_error(SecurityError)
43
+ end
44
+
45
+ it "should raise SecurityError when try to run shell cmd by calling system method" do
46
+ priv = Shikashi::Privileges.new
47
+ lambda {
48
+ Shikashi::Sandbox.new.run("system('ls')", priv)
49
+ }.should raise_error(SecurityError)
50
+ end
51
+
52
+ it "should raise SecurityError when try to run shell cmd by calling exec method" do
53
+ priv = Shikashi::Privileges.new
54
+ lambda {
55
+ Shikashi::Sandbox.new.run("exec('ls')", priv)
56
+ }.should raise_error(SecurityError)
57
+ end
58
+
59
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shikashi-the-north
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Joey Perira
8
+ - Adam Williams
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-08-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: evalhook
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: 0.6.0
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: 0.6.0
28
+ - !ruby/object:Gem::Dependency
29
+ name: getsource
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: 0.2.2
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: 0.2.2
42
+ description: 'Shikashi allows whitelisting specific language features, from constants,
43
+ to system modules, to arbitrary functions. This allows compete control over what
44
+ evaluated code can do, restricting use outside of specification. WARNING: changes
45
+ made in this package are experimental and can cause security flaws at the gain of
46
+ performance.'
47
+ email:
48
+ - joey@pereira.io
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - AUTHORS
54
+ - CHANGELOG
55
+ - Gemfile
56
+ - LICENSE
57
+ - README
58
+ - Rakefile
59
+ - TODO
60
+ - examples/basic/example.rb
61
+ - examples/basic/example1.rb
62
+ - examples/basic/example2.rb
63
+ - examples/basic/example3.rb
64
+ - examples/basic/example4.rb
65
+ - examples/basic/example5.rb
66
+ - examples/basic/example6.rb
67
+ - examples/basic/example7.rb
68
+ - examples/basic/example8.rb
69
+ - examples/benchmark/bm1.rb
70
+ - examples/benchmark/bm2.rb
71
+ - examples/timeout/example1.rb
72
+ - lib/shikashi.rb
73
+ - lib/shikashi/pick_argument.rb
74
+ - lib/shikashi/privileges.rb
75
+ - lib/shikashi/privileges/classes.rb
76
+ - lib/shikashi/privileges/exceptions.rb
77
+ - lib/shikashi/privileges/singleton_methods.rb
78
+ - lib/shikashi/sandbox.rb
79
+ - shikashi.gemspec
80
+ - spec/functional/encoding_spec.rb
81
+ - spec/functional/timeout_spec.rb
82
+ - spec/sandbox/privileges_sugar_syntax_spec.rb
83
+ - spec/sandbox/sandbox_hook_handler_spec.rb
84
+ - spec/sandbox/sandbox_spec.rb
85
+ - spec/sandbox/sugar_syntax_spec.rb
86
+ - spec/security/system_calls_spec.rb
87
+ homepage: https://github.com/xLegoz/shikashi
88
+ licenses: []
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.2.2
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: Shikashi is a ruby sandbox for running arbitrary Ruby code with eval.
110
+ test_files:
111
+ - spec/functional/encoding_spec.rb
112
+ - spec/functional/timeout_spec.rb
113
+ - spec/sandbox/privileges_sugar_syntax_spec.rb
114
+ - spec/sandbox/sandbox_hook_handler_spec.rb
115
+ - spec/sandbox/sandbox_spec.rb
116
+ - spec/sandbox/sugar_syntax_spec.rb
117
+ - spec/security/system_calls_spec.rb