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,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "shikashi-the-north"
7
+ gem.version = '0.1'
8
+
9
+ gem.files = `git ls-files`.split($/)
10
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
11
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
12
+ gem.require_paths = ["lib"]
13
+
14
+ gem.authors = ["Joey Perira", "Adam Williams"]
15
+ gem.email = ["joey@pereira.io"]
16
+ gem.summary = %q{Shikashi is a ruby sandbox for running arbitrary Ruby code with eval.}
17
+ gem.description = %q{Shikashi allows whitelisting specific language features, from constants, to system modules, to arbitrary functions. This allows compete control over what evaluated code can do, restricting use outside of specification. WARNING: changes made in this package are experimental and can cause security flaws at the gain of performance.}
18
+ gem.homepage = "https://github.com/xLegoz/shikashi"
19
+ # gem.license = 'MIT'
20
+
21
+ gem.add_dependency 'evalhook', '~> 0.6.0'
22
+ gem.add_dependency 'getsource', '~> 0.2.2'
23
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+ require "test/unit"
3
+ require "shikashi"
4
+
5
+ include Shikashi
6
+
7
+ describe Sandbox, "Shikashi sandbox" do
8
+ it "Should accept UTF-8 encoding via ruby header comments" do
9
+ Sandbox.new.run("# encoding: utf-8\n'кириллица'").should be == 'кириллица'
10
+ end
11
+
12
+ it "Should accept UTF-8 encoding via sandbox run options" do
13
+ Sandbox.new.run("'кириллица'", :encoding => "utf-8").should be == 'кириллица'
14
+ end
15
+
16
+ it "Should accept UTF-8 encoding via ruby header comments" do
17
+ Sandbox.new.run("# encoding: utf-8\n'кириллица'").should be == 'кириллица'
18
+ end
19
+
20
+ it "Should accept UTF-8 encoding via ruby header comments" do
21
+ Sandbox.new.run("# encoding: utf-8\n'кириллица'").should be == 'кириллица'
22
+ end
23
+
24
+ it "Should accept UTF-8 encoding via ruby header comments" do
25
+ Sandbox.new.packet("# encoding: utf-8\n'кириллица'").run.should be == 'кириллица'
26
+ end
27
+
28
+ it "Should accept UTF-8 encoding via sandbox run options" do
29
+ Sandbox.new.packet("'кириллица'", :encoding => "utf-8").run.should be == 'кириллица'
30
+ end
31
+
32
+ it "Should accept UTF-8 encoding via ruby header comments" do
33
+ Sandbox.new.packet("# encoding: utf-8\n'кириллица'").run.should be == 'кириллица'
34
+ end
35
+
36
+ it "Should accept UTF-8 encoding via ruby header comments" do
37
+ Sandbox.new.packet("# encoding: utf-8\n'кириллица'").run.should be == 'кириллица'
38
+ end
39
+ end
@@ -0,0 +1,57 @@
1
+ =begin
2
+
3
+ This file is part of the shikashi project, http://github.com/tario/shikashi
4
+
5
+ Copyright (c) 2009-2010 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ shikashi is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ shikashi is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with shikashi. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ require "test/unit"
22
+ require "shikashi"
23
+
24
+ include Shikashi
25
+
26
+ describe Sandbox, "Shikashi sandbox" do
27
+
28
+ def self.add_test(name, execution_delay, timeout)
29
+ if execution_delay > timeout
30
+ it "Should allow timeout of type #{name}" do
31
+ priv = Shikashi::Privileges.new
32
+ priv.allow_method :sleep
33
+
34
+ lambda {
35
+ Sandbox.new.run "sleep #{execution_delay}", priv, :timeout => timeout
36
+ }.should raise_error(Shikashi::Timeout::Error)
37
+ end
38
+ else
39
+ it "Should allow timeout of type #{name}" do
40
+ priv = Shikashi::Privileges.new
41
+ priv.allow_method :sleep
42
+
43
+ Sandbox.new.run "sleep #{execution_delay}", priv, :timeout => timeout
44
+
45
+ end
46
+
47
+ end
48
+ end
49
+
50
+ add_test "basic",2,1
51
+ add_test "float",0.2,0.1
52
+ add_test "float_no_hit",0.1,0.2
53
+ add_test "zero", 1,0
54
+ add_test "zero_no_hit", 0,1
55
+
56
+ end
57
+
@@ -0,0 +1,160 @@
1
+ require "shikashi"
2
+
3
+ include Shikashi
4
+
5
+ describe Privileges, "Shikashi::Privileges" do
6
+
7
+ # method chaining
8
+ it "allow_method should return object of Privileges class" do
9
+ Privileges.allow_method(:foo).should be_kind_of(Privileges)
10
+ end
11
+
12
+ it "allow_global_read should return object of Privileges class" do
13
+ Privileges.allow_global_read(:$a).should be_kind_of(Privileges)
14
+ end
15
+
16
+ it "allow_global_write should return object of Privileges class" do
17
+ Privileges.allow_global_write(:$a).should be_kind_of(Privileges)
18
+ end
19
+
20
+ it "allow_const_read should return object of Privileges class" do
21
+ Privileges.allow_const_read(:$a).should be_kind_of(Privileges)
22
+ end
23
+
24
+ it "allow_const_write should return object of Privileges class" do
25
+ Privileges.allow_const_write(:$a).should be_kind_of(Privileges)
26
+ end
27
+
28
+ it "allow_xstr should return object of Privileges class" do
29
+ Privileges.allow_xstr.should be_kind_of(Privileges)
30
+ end
31
+
32
+ it "instances_of(...).allow() should return object of Privileges class" do
33
+ Privileges.instances_of(Fixnum).allow("foo").should be_kind_of(Privileges)
34
+ end
35
+
36
+ it "object(...).allow() should return object of Privileges class" do
37
+ Privileges.object(Fixnum).allow("foo").should be_kind_of(Privileges)
38
+ end
39
+
40
+ it "methods_of(...).allow() should return object of Privileges class" do
41
+ Privileges.methods_of(Fixnum).allow("foo").should be_kind_of(Privileges)
42
+ end
43
+
44
+ it "instances_of(...).allow() should return object of Privileges class" do
45
+ Privileges.instances_of(Fixnum).allow_all.should be_kind_of(Privileges)
46
+ end
47
+
48
+ it "object(...).allow() should return object of Privileges class" do
49
+ Privileges.object(Fixnum).allow_all.should be_kind_of(Privileges)
50
+ end
51
+
52
+ it "methods_of(...).allow() should return object of Privileges class" do
53
+ Privileges.methods_of(Fixnum).allow_all.should be_kind_of(Privileges)
54
+ end
55
+
56
+ it "should chain one allow_method" do
57
+ priv = Privileges.allow_method(:to_s)
58
+ priv.allow?(Fixnum,4,:to_s,0).should be == true
59
+ end
60
+
61
+ it "should chain one allow_method and one allow_global" do
62
+ priv = Privileges.
63
+ allow_method(:to_s).
64
+ allow_global_read(:$a)
65
+
66
+ priv.allow?(Fixnum,4,:to_s,0).should be == true
67
+ priv.global_read_allowed?(:$a).should be == true
68
+ end
69
+
70
+ # argument conversion
71
+ it "should allow + method (as string)" do
72
+ priv = Privileges.new
73
+ priv.allow_method("+")
74
+ priv.allow?(Fixnum,4,:+,0).should be == true
75
+ end
76
+
77
+ it "should allow + method (as symbol)" do
78
+ priv = Privileges.new
79
+ priv.allow_method(:+)
80
+ priv.allow?(Fixnum,4,:+,0).should be == true
81
+ end
82
+
83
+ it "should allow $a global read (as string)" do
84
+ priv = Privileges.new
85
+ priv.allow_global_read("$a")
86
+ priv.global_read_allowed?(:$a).should be == true
87
+ end
88
+
89
+ it "should allow $a global read (as symbol)" do
90
+ priv = Privileges.new
91
+ priv.allow_global_read(:$a)
92
+ priv.global_read_allowed?(:$a).should be == true
93
+ end
94
+
95
+ it "should allow multiple global read (as symbol) in only one allow_global_read call" do
96
+ priv = Privileges.new
97
+ priv.allow_global_read(:$a, :$b)
98
+ priv.global_read_allowed?(:$a).should be == true
99
+ priv.global_read_allowed?(:$b).should be == true
100
+ end
101
+
102
+ it "should allow $a global write (as string)" do
103
+ priv = Privileges.new
104
+ priv.allow_global_write("$a")
105
+ priv.global_write_allowed?(:$a).should be == true
106
+ end
107
+
108
+ it "should allow $a global write (as symbol)" do
109
+ priv = Privileges.new
110
+ priv.allow_global_write(:$a)
111
+ priv.global_write_allowed?(:$a).should be == true
112
+ end
113
+
114
+ it "should allow multiple global write (as symbol) in only one allow_global_write call" do
115
+ priv = Privileges.new
116
+ priv.allow_global_write(:$a, :$b)
117
+ priv.global_write_allowed?(:$a).should be == true
118
+ priv.global_write_allowed?(:$b).should be == true
119
+ end
120
+
121
+ # constants
122
+
123
+ it "should allow constant read (as string)" do
124
+ priv = Privileges.new
125
+ priv.allow_const_read("TESTCONSTANT")
126
+ priv.const_read_allowed?("TESTCONSTANT").should be == true
127
+ end
128
+
129
+ it "should allow constant read (as symbol)" do
130
+ priv = Privileges.new
131
+ priv.allow_const_read(:TESTCONSTANT)
132
+ priv.const_read_allowed?("TESTCONSTANT").should be == true
133
+ end
134
+
135
+ it "should allow multiple constant read (as string) in only one allow_const_read call" do
136
+ priv = Privileges.new
137
+ priv.allow_const_read("TESTCONSTANT1", "TESTCONSTANT2")
138
+ priv.const_read_allowed?("TESTCONSTANT1").should be == true
139
+ priv.const_read_allowed?("TESTCONSTANT2").should be == true
140
+ end
141
+
142
+ it "should allow constant write (as string)" do
143
+ priv = Privileges.new
144
+ priv.allow_const_write("TESTCONSTANT")
145
+ priv.const_write_allowed?("TESTCONSTANT").should be == true
146
+ end
147
+
148
+ it "should allow constant write (as symbol)" do
149
+ priv = Privileges.new
150
+ priv.allow_const_write(:TESTCONSTANT)
151
+ priv.const_write_allowed?("TESTCONSTANT").should be == true
152
+ end
153
+
154
+ it "should allow multiple constant write (as symbol) in only one allow_const_write call" do
155
+ priv = Privileges.new
156
+ priv.allow_const_write("TESTCONSTANT1", "TESTCONSTANT2")
157
+ priv.const_write_allowed?("TESTCONSTANT1").should be == true
158
+ priv.const_write_allowed?("TESTCONSTANT2").should be == true
159
+ end
160
+ end
@@ -0,0 +1,181 @@
1
+ require "rubygems"
2
+ require "shikashi"
3
+ require "evalhook"
4
+
5
+ include Shikashi
6
+
7
+ describe Sandbox, "Shikashi sandbox hook handler" do
8
+
9
+ it "should be obtainable from sandbox" do
10
+ Sandbox.new.hook_handler
11
+ end
12
+
13
+ it "should be obtainable from sandbox through create_hook_handler" do
14
+ sandbox = Sandbox.new
15
+ hook_handler = sandbox.create_hook_handler()
16
+ hook_handler.should be_kind_of(EvalHook::HookHandler)
17
+ end
18
+
19
+ class X
20
+ def foo
21
+
22
+ end
23
+ end
24
+ it "should raise SecurityError when handle calls without privileges" do
25
+ sandbox = Sandbox.new
26
+ hook_handler = sandbox.create_hook_handler()
27
+
28
+ x = X.new
29
+ lambda {
30
+ hook_handler.handle_method(X,x,:foo)
31
+ }.should raise_error(SecurityError)
32
+
33
+ end
34
+
35
+ it "should not raise SecurityError with method privileges" do
36
+ sandbox = Sandbox.new
37
+ priv = Privileges.new
38
+ priv.allow_method(:foo)
39
+
40
+ hook_handler = sandbox.create_hook_handler(:privileges => priv, :source => "test-source")
41
+
42
+ def hook_handler.get_caller
43
+ "test-source"
44
+ end
45
+
46
+ x = X.new
47
+ lambda {
48
+ hook_handler.handle_method(X,x,:foo)
49
+
50
+ }.should_not raise_error
51
+
52
+ end
53
+
54
+ it "should raise SecurityError with handle_gasgn without privileges" do
55
+ sandbox = Sandbox.new
56
+
57
+ hook_handler = sandbox.create_hook_handler(:source => "test-source")
58
+
59
+ def hook_handler.get_caller
60
+ "test-source"
61
+ end
62
+
63
+ lambda {
64
+ hook_handler.handle_gasgn(:$a,nil)
65
+ }.should raise_error(SecurityError)
66
+ end
67
+
68
+ it "should not raise SecurityError with handle_gasgn with privileges" do
69
+ sandbox = Sandbox.new
70
+ privileges = Privileges.new
71
+
72
+ privileges.allow_global_write(:$a)
73
+
74
+ hook_handler = sandbox.create_hook_handler(:privileges => privileges, :source => "test-source")
75
+
76
+ def hook_handler.get_caller
77
+ "test-source"
78
+ end
79
+
80
+ lambda {
81
+ hook_handler.handle_gasgn(:$a,nil)
82
+ }.should_not raise_error
83
+ end
84
+
85
+ it "should raise SecurityError with handle_cdecl without privileges" do
86
+ sandbox = Sandbox.new
87
+
88
+ hook_handler = sandbox.create_hook_handler(:source => "test-source")
89
+
90
+ def hook_handler.get_caller
91
+ "test-source"
92
+ end
93
+
94
+ lambda {
95
+ hook_handler.handle_cdecl(Object,:A,nil)
96
+ }.should raise_error(SecurityError)
97
+ end
98
+
99
+ it "should not raise SecurityError with handle_cdecl with privileges" do
100
+ sandbox = Sandbox.new
101
+ privileges = Privileges.new
102
+
103
+ privileges.allow_const_write("Object::A")
104
+
105
+ hook_handler = sandbox.create_hook_handler(:privileges => privileges, :source => "test-source")
106
+
107
+ def hook_handler.get_caller
108
+ "test-source"
109
+ end
110
+
111
+ lambda {
112
+ hook_handler.handle_cdecl(Object,:A,nil)
113
+ }.should_not raise_error
114
+ end
115
+
116
+
117
+
118
+ it "should raise SecurityError with handle_gvar without privileges" do
119
+ sandbox = Sandbox.new
120
+
121
+ hook_handler = sandbox.create_hook_handler(:source => "test-source")
122
+
123
+ def hook_handler.get_caller
124
+ "test-source"
125
+ end
126
+
127
+ lambda {
128
+ hook_handler.handle_gvar(:$a)
129
+ }.should raise_error(SecurityError)
130
+ end
131
+
132
+ it "should not raise SecurityError with handle_gasgn with privileges" do
133
+ sandbox = Sandbox.new
134
+ privileges = Privileges.new
135
+
136
+ privileges.allow_global_read(:$a)
137
+
138
+ hook_handler = sandbox.create_hook_handler(:privileges => privileges, :source => "test-source")
139
+
140
+ def hook_handler.get_caller
141
+ "test-source"
142
+ end
143
+
144
+ lambda {
145
+ hook_handler.handle_gvar(:$a)
146
+ }.should_not raise_error
147
+ end
148
+
149
+ it "should raise SecurityError with handle_const without privileges" do
150
+ sandbox = Sandbox.new
151
+
152
+ hook_handler = sandbox.create_hook_handler(:source => "test-source")
153
+
154
+ def hook_handler.get_caller
155
+ "test-source"
156
+ end
157
+
158
+ lambda {
159
+ hook_handler.handle_const(:A)
160
+ }.should raise_error(SecurityError)
161
+ end
162
+
163
+ it "should not raise SecurityError with handle_cdecl with privileges" do
164
+ sandbox = Sandbox.new
165
+ privileges = Privileges.new
166
+
167
+ ::A = nil
168
+ privileges.allow_const_read("A")
169
+
170
+ hook_handler = sandbox.create_hook_handler(:privileges => privileges, :source => "test-source")
171
+
172
+ def hook_handler.get_caller
173
+ "test-source"
174
+ end
175
+
176
+ lambda {
177
+ hook_handler.handle_const(:A)
178
+ }.should_not raise_error
179
+ end
180
+
181
+ end