shikashi-the-north 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,222 @@
1
+ = Shikashi - A flexible sandbox for ruby
2
+
3
+ Shikashi is an sandbox for ruby that handles all ruby method calls executed in the interpreter to allow or deny
4
+ these calls depending on the receiver object, the method name, the source file from where the call was originated
5
+ and the source file where the called method is implemented.
6
+
7
+ The permissions for each sandboxed run is fully configurable and the implementation of the methods called from within
8
+ the sandbox can be replaced transparently
9
+
10
+ The implementation of shikashi is written in pure ruby and now implemented based in evalhook, (see http://tario.github.com/evalhook)
11
+
12
+ == Installation
13
+
14
+ === Gem installation
15
+
16
+ Run in the terminal:
17
+
18
+ sudo gem install shikashi
19
+
20
+ OR
21
+
22
+ * Download the last version of the gem from http://github.com/tario/shikashi/downloads
23
+ * Install the gem with the following;
24
+
25
+ sudo gem install shikashi-X.X.X.gem.
26
+
27
+ === Troubleshooting
28
+
29
+ ERROR: While executing gem ... (Gem::DependencyError)
30
+ Unable to resolve dependencies: ruby2ruby requires sexp_processor (~> 3.0); ruby_parser requires sexp_processor (~> 3.0)
31
+
32
+ The version of ruby2ruby and ruby_parser required depends on sexp_processor 3.X but for some reason this version of the gem
33
+ is not automatically installed by gem, you can workaround this issue by installing it before using:
34
+
35
+ gem install sexp_processor --version '~> 3.2'
36
+
37
+ == Documentation
38
+
39
+ Full API documentation can be found on:
40
+ http://tario.github.com/shikashi/doc/
41
+
42
+ == Usage
43
+
44
+ This examples and more can be found in examples directory
45
+
46
+ === Basic Example
47
+
48
+ Hello world from a sandbox
49
+
50
+ require "rubygems"
51
+ require "shikashi"
52
+
53
+ include Shikashi
54
+
55
+ s = Sandbox.new
56
+ priv = Privileges.new
57
+ priv.allow_method :print
58
+
59
+ s.run(priv, 'print "hello world\n"')
60
+
61
+ === Basic Example 2
62
+
63
+ Call external method from inside the sandbox
64
+
65
+ require "rubygems"
66
+ require "shikashi"
67
+
68
+ include Shikashi
69
+
70
+ def foo
71
+ # privileged code, can do any operation
72
+ print "foo\n"
73
+ end
74
+
75
+ s = Sandbox.new
76
+ priv = Privileges.new
77
+
78
+ # allow execution of foo in this object
79
+ priv.object(self).allow :foo
80
+
81
+ # allow execution of method :times on instances of Fixnum
82
+ priv.instances_of(Fixnum).allow :times
83
+
84
+ #inside the sandbox, only can use method foo on main and method times on instances of Fixnum
85
+ s.run(priv, "2.times do foo end")
86
+
87
+ === Basic Example 3
88
+
89
+ Define a class outside the sandbox and use it in the sandbox
90
+
91
+ require "rubygems"
92
+ require "shikashi"
93
+
94
+ include Shikashi
95
+
96
+ s = Sandbox.new
97
+ priv = Privileges.new
98
+
99
+ # allow execution of print
100
+ priv.allow_method :print
101
+
102
+ class X
103
+ def foo
104
+ print "X#foo\n"
105
+ end
106
+
107
+ def bar
108
+ system("echo hello world") # accepted, called from privileged context
109
+ end
110
+
111
+ def privileged_operation( out )
112
+ # write to file specified in out
113
+ system("echo privileged operation > " + out)
114
+ end
115
+ end
116
+ # allow method new of class X
117
+ priv.object(X).allow :new
118
+
119
+ # allow instance methods of X. Note that the method privileged_operations is not allowed
120
+ priv.instances_of(X).allow :foo, :bar
121
+
122
+ priv.allow_method :=== # for exception handling
123
+ #inside the sandbox, only can use method foo on main and method times on instances of Fixnum
124
+ s.run(priv, '
125
+ x = X.new
126
+ x.foo
127
+ x.bar
128
+
129
+ begin
130
+ x.privileged_operation # FAIL
131
+ rescue SecurityError
132
+ print "privileged_operation failed due security error\n"
133
+ end
134
+ ')
135
+
136
+ === Basic Example 4
137
+
138
+ define a class from inside the sandbox and use it from outside
139
+
140
+ require "rubygems"
141
+ require "shikashi"
142
+
143
+ include Shikashi
144
+
145
+ s = Sandbox.new
146
+ priv = Privileges.new
147
+
148
+ # allow execution of print
149
+ priv.allow_method :print
150
+
151
+ #inside the sandbox, only can use method foo on main and method times on instances of Fixnum
152
+ s.run(priv, '
153
+ class X
154
+ def foo
155
+ print "X#foo\n"
156
+ end
157
+
158
+ def bar
159
+ system("ls -l")
160
+ end
161
+ end
162
+ ')
163
+
164
+ x = s.base_namespace::X.new
165
+ x.foo
166
+ begin
167
+ x.bar
168
+ rescue SecurityError => e
169
+ print "x.bar failed due security errors: #{e}\n"
170
+ end
171
+
172
+
173
+ === Base namespace
174
+
175
+ require "rubygems"
176
+ require "shikashi"
177
+
178
+ include Shikashi
179
+
180
+ class X
181
+ def foo
182
+ print "X#foo\n"
183
+ end
184
+ end
185
+
186
+ s = Sandbox.new
187
+
188
+ s.run( "
189
+ class X
190
+ def foo
191
+ print \"foo defined inside the sandbox\\n\"
192
+ end
193
+ end
194
+ ", Privileges.allow_method(:print))
195
+
196
+
197
+ x = X.new # X class is not affected by the sandbox (The X Class defined in the sandbox is SandboxModule::X)
198
+ x.foo
199
+
200
+ x = s.base_namespace::X.new
201
+ x.foo
202
+
203
+ s.run("X.new.foo", Privileges.allow_method(:new).allow_method(:foo))
204
+
205
+
206
+
207
+ === Timeout example
208
+
209
+ require "rubygems"
210
+ require "shikashi"
211
+
212
+ s = Shikashi::Sandbox.new
213
+ perm = Shikashi::Privileges.new
214
+
215
+ perm.allow_method :sleep
216
+
217
+ s.run(perm,"sleep 3", :timeout => 2) # raise Shikashi::Timeout::Error after 2 seconds
218
+
219
+
220
+ == Copying
221
+
222
+ Copyright (c) 2010-2011 Dario Seminara, released under the GPL License (see LICENSE)
@@ -0,0 +1,40 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rdoc/task'
4
+ require 'rubygems/package_task'
5
+ require 'rake/testtask'
6
+
7
+ spec = Gem::Specification.new do |s|
8
+ s.name = 'shikashi'
9
+ s.version = '0.6.0'
10
+ s.author = 'Dario Seminara'
11
+ s.email = 'robertodarioseminara@gmail.com'
12
+ s.platform = Gem::Platform::RUBY
13
+ s.summary = 'shikashi is a ruby sandbox that permits the execution of "unprivileged" scripts by defining the permitted methods and constants the scripts can invoke with a white list logic'
14
+ s.homepage = "http://github.com/tario/shikashi"
15
+ s.add_dependency "evalhook", ">= 0.6.0"
16
+ s.add_dependency "getsource", ">= 0.1.0"
17
+ s.has_rdoc = true
18
+ s.extra_rdoc_files = [ 'README' ]
19
+ # s.rdoc_options << '--main' << 'README'
20
+ s.files = Dir.glob("{examples,lib,test}/**/*") +
21
+ [ 'LICENSE', 'AUTHORS', 'CHANGELOG', 'README', 'Rakefile', 'TODO' ]
22
+ end
23
+
24
+ desc 'Generate RDoc'
25
+ Rake::RDocTask.new :rdoc do |rd|
26
+ rd.rdoc_dir = 'doc'
27
+ rd.rdoc_files.add 'lib', 'README'
28
+ rd.main = 'README'
29
+ end
30
+
31
+ desc 'Build Gem'
32
+ Gem::PackageTask.new spec do |pkg|
33
+ pkg.need_tar = true
34
+ end
35
+
36
+ desc 'Clean up'
37
+ task :clean => [ :clobber_rdoc, :clobber_package ]
38
+
39
+ desc 'Clean up'
40
+ task :clobber => [ :clean ]
data/TODO ADDED
@@ -0,0 +1,2 @@
1
+
2
+ * Remove the rallhook gem dependency (is currentily used to read the source file of the called methods)
@@ -0,0 +1,29 @@
1
+ # call method defined in sandbox from outside
2
+ require "rubygems"
3
+ require "shikashi"
4
+
5
+ include Shikashi
6
+
7
+ s = Sandbox.new
8
+ priv = Privileges.new
9
+
10
+ # allow execution of foo in this object
11
+ priv.object(self).allow :foo
12
+
13
+ # allow execution of print in this object
14
+ priv.object(self).allow :print
15
+
16
+ #inside the sandbox, only can use method foo on main and method times on instances of Fixnum
17
+ code = "
18
+ def inside_foo(a)
19
+ print 'inside_foo'
20
+ if (a)
21
+ system('ls -l') # denied
22
+ end
23
+ end
24
+ "
25
+
26
+ s.run(code, priv, :no_base_namespace => true)
27
+
28
+ inside_foo(false)
29
+ #inside_foo(true) #SecurityError
@@ -0,0 +1,12 @@
1
+ # "hello world" from within the sandbox
2
+
3
+ require "rubygems"
4
+ require "shikashi"
5
+
6
+ include Shikashi
7
+
8
+ s = Sandbox.new
9
+ priv = Privileges.new
10
+ priv.allow_method :print
11
+
12
+ s.run(priv, 'print "hello world\n"')
@@ -0,0 +1,24 @@
1
+ # call external method from inside the sandbox
2
+
3
+ require "rubygems"
4
+ require "shikashi"
5
+
6
+ include Shikashi
7
+
8
+ def foo
9
+ # privileged code, can do any operation
10
+ print "foo\n"
11
+ end
12
+
13
+ s = Sandbox.new
14
+ priv = Privileges.new
15
+
16
+ # allow execution of foo in this object
17
+ priv.object(self).allow :foo
18
+
19
+ # allow execution of method :times on instances of Fixnum
20
+ priv.instances_of(Fixnum).allow :times
21
+
22
+ #inside the sandbox, only can use method foo on main and method times on instances of Fixnum
23
+ s.run(priv, "2.times do foo end", :no_base_namespace => true)
24
+
@@ -0,0 +1,43 @@
1
+ # define a class outside the sandbox and use it in the sandbox
2
+
3
+ require "rubygems"
4
+ require "shikashi"
5
+
6
+ include Shikashi
7
+
8
+ s = Sandbox.new
9
+
10
+ class X
11
+ def foo
12
+ print "X#foo\n"
13
+ end
14
+
15
+ def bar
16
+ system("echo hello world") # accepted, called from privileged context
17
+ end
18
+
19
+ def privileged_operation( out )
20
+ # write to file specified in out
21
+ system("echo privileged operation > " + out)
22
+ end
23
+ end
24
+
25
+
26
+ priv = Privileges.
27
+ allow_method(:print). # allow execution of print
28
+ object(X).allow(:new). # allow method new of class X
29
+ instances_of(X).allow(:foo, :bar). # allow instance methods of X. Note that the method privileged_operations is not allowed
30
+ allow_const_read("X","SecurityError") # allow the access of X constant
31
+
32
+ #inside the sandbox, only can use method foo on main and method times on instances of Fixnum
33
+ s.run(priv, '
34
+ x = X.new
35
+ x.foo
36
+ x.bar
37
+
38
+ begin
39
+ x.privileged_operation # FAIL
40
+ rescue SecurityError
41
+ print "privileged_operation failed due security error\n"
42
+ end
43
+ ')
@@ -0,0 +1,33 @@
1
+ # call method defined in sandbox from outside
2
+
3
+ require "rubygems"
4
+ require "shikashi"
5
+
6
+ include Shikashi
7
+
8
+ s = Sandbox.new
9
+ priv = Privileges.new
10
+
11
+ # allow execution of print
12
+ priv.allow_method :print
13
+
14
+ #inside the sandbox, only can use method foo on main and method times on instances of Fixnum
15
+ s.run(priv, '
16
+ module A
17
+ def self.inside_foo(a)
18
+ print "inside_foo\n"
19
+ if (a)
20
+ system("ls -l") # denied
21
+ end
22
+ end
23
+ end
24
+ ')
25
+
26
+ # run privileged code in the sandbox, if not, the methods defined in the sandbox are invisible from outside
27
+ s.base_namespace::A.inside_foo(false)
28
+ begin
29
+ s.base_namespace::A.inside_foo(true)
30
+ rescue SecurityError => e
31
+ print "A.inside_foo(true) failed due security errors: #{e}\n"
32
+ end
33
+
@@ -0,0 +1,38 @@
1
+ # define a class from inside the sandbox and use it from outside
2
+
3
+ require "rubygems"
4
+ require "shikashi"
5
+
6
+ include Shikashi
7
+
8
+ s = Sandbox.new
9
+ priv = Privileges.new
10
+
11
+ # allow execution of print
12
+ priv.allow_method :print
13
+
14
+ # allow definition of classes
15
+ priv.allow_class_definitions
16
+
17
+ #inside the sandbox, only can use method foo on main and method times on instances of Fixnum
18
+ s.run(priv, '
19
+ class X
20
+ def foo
21
+ print "X#foo\n"
22
+ end
23
+
24
+ def bar
25
+ system("ls -l")
26
+ end
27
+ end
28
+ ')
29
+
30
+ # run privileged code in the sandbox, if not, the methods defined in the sandbox are invisible from outside
31
+ x = s.base_namespace::X.new
32
+ x.foo
33
+ begin
34
+ x.bar
35
+ rescue SecurityError => e
36
+ print "x.bar failed due security errors: #{e}\n"
37
+ end
38
+