build_box 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Rakefile +1 -0
- data/lib/build_box/config.rb +21 -19
- data/lib/build_box/perform.rb +34 -33
- data/lib/build_box/response.rb +10 -8
- data/lib/build_box/version.rb +1 -1
- data/lib/build_box.rb +2 -2
- data/spec/build_box_spec.rb +16 -12
- data/spec/spec_helper.rb +1 -1
- metadata +2 -3
- data/Gemfile.lock +0 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ee932e6eaa693236f9ee28629c286aa91dd3788
|
4
|
+
data.tar.gz: 68f0e6cffe4e763d55a59a5406eee999e618654f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4327242827f1cd0e1c0d18643061133fdcc05b7275764ad9d737919df649ae8004cddce6535eb6cb85ef128217d9cbd65980f6619a131c7e93727a440eb0c81
|
7
|
+
data.tar.gz: c2d3889254677bfa8870ec4635a773d34bd7da2a089c58052971c725fe8f04f14b008aae8444a6ab97e612c4f9459c43c20662d346d6f5a05bacb7aee4245b25
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
data/lib/build_box/config.rb
CHANGED
@@ -9,24 +9,24 @@ module BuildBox
|
|
9
9
|
option :bad_methods, :default => [
|
10
10
|
[:Object, :abort],
|
11
11
|
[:Kernel, :abort],
|
12
|
-
[:Object, :autoload],
|
13
|
-
[:Kernel, :autoload],
|
14
|
-
[:Object, :autoload?],
|
15
|
-
[:Kernel, :autoload?],
|
12
|
+
# [:Object, :autoload],
|
13
|
+
# [:Kernel, :autoload],
|
14
|
+
# [:Object, :autoload?],
|
15
|
+
# [:Kernel, :autoload?],
|
16
16
|
[:Object, :callcc],
|
17
17
|
[:Kernel, :callcc],
|
18
|
-
[:Object, :exit],
|
19
|
-
[:Kernel, :exit],
|
20
|
-
[:Object, :exit!],
|
21
|
-
[:Kernel, :exit!],
|
22
|
-
[:Object, :at_exit],
|
23
|
-
[:Kernel, :at_exit],
|
18
|
+
# [:Object, :exit],
|
19
|
+
# [:Kernel, :exit],
|
20
|
+
# [:Object, :exit!],
|
21
|
+
# [:Kernel, :exit!],
|
22
|
+
# [:Object, :at_exit],
|
23
|
+
# [:Kernel, :at_exit],
|
24
24
|
[:Object, :exec],
|
25
25
|
[:Kernel, :exec],
|
26
26
|
[:Object, :fork],
|
27
27
|
[:Kernel, :fork],
|
28
|
-
[:Object, :load],
|
29
|
-
[:Kernel, :load],
|
28
|
+
# [:Object, :load],
|
29
|
+
# [:Kernel, :load],
|
30
30
|
[:Object, :open],
|
31
31
|
[:Kernel, :open],
|
32
32
|
[:Object, :set_trace_func],
|
@@ -37,22 +37,24 @@ module BuildBox
|
|
37
37
|
[:Kernel, :syscall],
|
38
38
|
[:Object, :system],
|
39
39
|
[:Kernel, :system],
|
40
|
-
[:Object, :test],
|
41
|
-
[:Kernel, :test],
|
40
|
+
# [:Object, :test],
|
41
|
+
# [:Kernel, :test],
|
42
42
|
[:Object, :remove_method],
|
43
43
|
[:Kernel, :remove_method],
|
44
|
-
[:Object, :require],
|
45
|
-
[:Kernel, :require],
|
46
|
-
[:Object, :require_relative],
|
47
|
-
[:Kernel, :require_relative],
|
44
|
+
# [:Object, :require],
|
45
|
+
# [:Kernel, :require],
|
46
|
+
# [:Object, :require_relative],
|
47
|
+
# [:Kernel, :require_relative],
|
48
48
|
[:Object, :undef_method],
|
49
49
|
[:Kernel, :undef_method],
|
50
50
|
[:Object, "`".to_sym],
|
51
51
|
[:Kernel, "`".to_sym],
|
52
52
|
[:Class, "`".to_sym]
|
53
53
|
]
|
54
|
-
|
54
|
+
|
55
|
+
option :bad_constants, :default => [:Continuation, :Open3, :File, :Dir, :IO, :BuildBox, :Process, :Thread, :Fiber, :Gem, :Net, :ThreadGroup]
|
55
56
|
|
56
57
|
option :timeout, :default => 3
|
58
|
+
option :security_level, :default => 3 # (0..3)
|
57
59
|
end
|
58
60
|
end
|
data/lib/build_box/perform.rb
CHANGED
@@ -2,10 +2,11 @@ class BuildBox::Perform
|
|
2
2
|
|
3
3
|
attr_accessor :output, :error, :code, :unbound_methods, :unbound_constants
|
4
4
|
|
5
|
-
def initialize(code)
|
5
|
+
def initialize(code, binding_context=TOPLEVEL_BINDING)
|
6
6
|
self.unbound_methods = []
|
7
7
|
self.unbound_constants = []
|
8
|
-
self.code
|
8
|
+
self.code = code
|
9
|
+
@binding_context = binding_context
|
9
10
|
evaluate
|
10
11
|
end
|
11
12
|
|
@@ -13,11 +14,11 @@ class BuildBox::Perform
|
|
13
14
|
|
14
15
|
def evaluate
|
15
16
|
t = Thread.new do
|
16
|
-
$SAFE =
|
17
|
+
$SAFE = BuildBox.config.security_level
|
17
18
|
begin
|
18
19
|
BuildBox.config.bad_methods.each {|meth| remove_method(meth.first, meth.last)}
|
19
20
|
BuildBox.config.bad_constants.each {|const| remove_constant(const)}
|
20
|
-
@output = eval(@code,
|
21
|
+
@output = eval(@code, @binding_context, "build_box")
|
21
22
|
@error = nil
|
22
23
|
rescue Exception => e
|
23
24
|
@error = "#{e.class}: #{e.to_s}"
|
@@ -39,46 +40,46 @@ class BuildBox::Perform
|
|
39
40
|
if const.methods.include?(method) || const.instance_methods.include?(method)
|
40
41
|
self.unbound_methods << [const, const.method(method).unbind]
|
41
42
|
metaclass = class << const; self; end
|
43
|
+
message = ''
|
44
|
+
if const == Object
|
45
|
+
message = "undefined local variable or method `#{method}' for main:Object"
|
46
|
+
else
|
47
|
+
message = "undefined local variable or method `#{method}' for #{klass}:#{const.class}"
|
48
|
+
end
|
42
49
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
"undefined local variable or method `#{method}' for #{klass}:#{const.class}"
|
47
|
-
end
|
48
|
-
|
49
|
-
metaclass.send(:define_method, method) do |*args|
|
50
|
-
raise NameError, message
|
51
|
-
end
|
50
|
+
metaclass.send(:define_method, method) do |*args|
|
51
|
+
raise NameError, message
|
52
|
+
end
|
52
53
|
|
53
|
-
|
54
|
-
|
54
|
+
const.send(:define_method, method) do |*args|
|
55
|
+
raise NameError, message
|
56
|
+
end
|
55
57
|
end
|
56
58
|
end
|
57
|
-
end
|
58
59
|
|
59
|
-
def restore_methods
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
def restore_methods
|
61
|
+
self.unbound_methods.each do |unbound|
|
62
|
+
klass = unbound.first
|
63
|
+
method = unbound.last
|
63
64
|
|
64
|
-
|
65
|
+
metaclass = class << klass; self; end
|
65
66
|
|
66
|
-
|
67
|
-
|
68
|
-
|
67
|
+
metaclass.send(:define_method, method.name) do |*args|
|
68
|
+
method.bind(klass).call(*args)
|
69
|
+
end
|
69
70
|
|
70
|
-
|
71
|
-
|
71
|
+
klass.send(:define_method, method.name) do |*args|
|
72
|
+
method.bind(klass).call(*args)
|
73
|
+
end
|
72
74
|
end
|
73
75
|
end
|
74
|
-
end
|
75
76
|
|
76
|
-
def remove_constant(constant)
|
77
|
-
|
78
|
-
end
|
77
|
+
def remove_constant(constant)
|
78
|
+
self.unbound_constants << Object.send(:remove_const, constant) if Object.const_defined?(constant)
|
79
|
+
end
|
79
80
|
|
80
|
-
def restore_constants
|
81
|
-
|
82
|
-
end
|
81
|
+
def restore_constants
|
82
|
+
self.unbound_constants.each {|const| Object.const_set(const.to_s.to_sym, const) unless Object.const_defined?(const.to_s.to_sym) rescue false}
|
83
|
+
end
|
83
84
|
|
84
85
|
end # BuildBox::Perform
|
data/lib/build_box/response.rb
CHANGED
@@ -1,31 +1,33 @@
|
|
1
1
|
class BuildBox::Response
|
2
2
|
|
3
|
-
attr_accessor :output, :error, :
|
3
|
+
attr_accessor :output, :error, :code # TODO: return de evaluated code
|
4
4
|
|
5
|
-
def initialize(code)
|
6
|
-
evaluate(code)
|
5
|
+
def initialize(code, binding_context)
|
6
|
+
evaluate(code, binding_context)
|
7
7
|
end
|
8
8
|
|
9
9
|
def error?
|
10
10
|
!@error.nil?
|
11
11
|
end
|
12
12
|
|
13
|
-
|
13
|
+
private
|
14
14
|
|
15
|
-
def evaluate(code)
|
15
|
+
def evaluate(code, binding_context)
|
16
16
|
preserve_namespace
|
17
|
-
result = BuildBox::Perform.new(code)
|
17
|
+
result = BuildBox::Perform.new(code, binding_context)
|
18
18
|
@output = result.output
|
19
19
|
@error = result.error
|
20
|
+
@code = result.code
|
20
21
|
restore_namespace
|
22
|
+
self
|
21
23
|
end
|
22
24
|
|
23
25
|
def preserve_namespace
|
24
|
-
|
26
|
+
@old_constants = Object.constants
|
25
27
|
end
|
26
28
|
|
27
29
|
def restore_namespace
|
28
|
-
(Object.constants -
|
30
|
+
(Object.constants - @old_constants).each {|bad_constant| Object.send(:remove_const, bad_constant)}
|
29
31
|
end
|
30
32
|
|
31
33
|
|
data/lib/build_box/version.rb
CHANGED
data/lib/build_box.rb
CHANGED
data/spec/build_box_spec.rb
CHANGED
@@ -33,15 +33,15 @@ describe "BuildBox" do
|
|
33
33
|
it 'allows constants to be used after uninitializing them' do
|
34
34
|
expect(BuildBox.config).to receive(:bad_methods).and_return([])
|
35
35
|
expect(BuildBox.config).to receive(:bad_constants).and_return([:Net])
|
36
|
+
expect(Object.const_get(:Net)).to_not raise_error
|
36
37
|
result = BuildBox.perform(' Net.methods')
|
37
38
|
expect(result.error?).to be_true
|
38
|
-
expect(Object.const_get(:Net)).to_not raise_error
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'allows methods to be called after removing them' do
|
42
|
-
expect(BuildBox.config).to receive(:bad_methods).and_return([
|
42
|
+
expect(BuildBox.config).to receive(:bad_methods).and_return([])
|
43
43
|
expect(BuildBox.config).to receive(:bad_constants).and_return([])
|
44
|
-
BuildBox.perform(
|
44
|
+
BuildBox.perform('a = 1 + 1; test;')
|
45
45
|
Kernel.methods.should include(:exit)
|
46
46
|
end
|
47
47
|
|
@@ -61,6 +61,11 @@ describe "BuildBox" do
|
|
61
61
|
expect(BuildBox.perform('Foo.new.test').error).to eql("NameError: uninitialized constant Foo")
|
62
62
|
end
|
63
63
|
|
64
|
+
it "permit add context varables" do
|
65
|
+
ctx = OpenStruct.new(:params => {a: 1, b: 2})
|
66
|
+
expect(BuildBox.perform('params[:a] + params[:b]', ctx.__binding__).output).to eql(3)
|
67
|
+
end
|
68
|
+
|
64
69
|
context 'unsafe commands' do
|
65
70
|
it 'does not exit' do
|
66
71
|
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([])
|
@@ -75,21 +80,21 @@ describe "BuildBox" do
|
|
75
80
|
end
|
76
81
|
|
77
82
|
it 'does not exec' do
|
78
|
-
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([])
|
83
|
+
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([[:Object, :exec]])
|
79
84
|
expect(BuildBox.config).to receive(:bad_constants).at_least(:once).and_return([])
|
80
|
-
expect(BuildBox.perform('exec("ps")').error).to
|
85
|
+
expect(BuildBox.perform('exec("ps")').error).to include("NameError: undefined local variable or method `exec' for")
|
81
86
|
end
|
82
87
|
|
83
88
|
it 'does not exec for kernel' do
|
84
|
-
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([])
|
89
|
+
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([[:Kernel, :exec]])
|
85
90
|
expect(BuildBox.config).to receive(:bad_constants).at_least(:once).and_return([])
|
86
|
-
expect(BuildBox.perform('Kernel.exec("ps")').error).to
|
91
|
+
expect(BuildBox.perform('Kernel.exec("ps")').error).to include("NameError: undefined local variable or method `exec' ")
|
87
92
|
end
|
88
93
|
|
89
94
|
it 'does not `' do
|
90
|
-
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([])
|
95
|
+
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([[:Object, "`".to_sym], [:Kernel, "`".to_sym], [:Class, "`".to_sym]])
|
91
96
|
expect(BuildBox.config).to receive(:bad_constants).at_least(:once).and_return([])
|
92
|
-
expect(BuildBox.perform('`ls`').error).to
|
97
|
+
expect(BuildBox.perform('`ls`').error).to include("NameError: undefined local variable or method ``' for")
|
93
98
|
end
|
94
99
|
|
95
100
|
it 'does not implement File' do
|
@@ -117,9 +122,8 @@ describe "BuildBox" do
|
|
117
122
|
end
|
118
123
|
|
119
124
|
it 'does not implement Open3 even after requiring it' do
|
120
|
-
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([])
|
121
|
-
expect(BuildBox.
|
122
|
-
expect(BuildBox.perform('require "open3"; Open3').error).to eql("SecurityError: Insecure operation - require")
|
125
|
+
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([[:Object,:require], [:kernel, :require]])
|
126
|
+
expect(BuildBox.perform('require "open3"; Open3').error?).to be_true #eql("SecurityError: Insecure operation - require")
|
123
127
|
end
|
124
128
|
|
125
129
|
it 'does not allow you to manually call protected BuildBox methods' do
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: build_box
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rafael Vettori
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -48,7 +48,6 @@ files:
|
|
48
48
|
- ".gitignore"
|
49
49
|
- ".rspec"
|
50
50
|
- Gemfile
|
51
|
-
- Gemfile.lock
|
52
51
|
- LICENSE.txt
|
53
52
|
- README.md
|
54
53
|
- Rakefile
|
data/Gemfile.lock
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
build_box (0.0.1)
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: https://rubygems.org/
|
8
|
-
specs:
|
9
|
-
coderay (1.1.0)
|
10
|
-
diff-lcs (1.2.5)
|
11
|
-
docile (1.1.3)
|
12
|
-
method_source (0.8.2)
|
13
|
-
multi_json (1.9.3)
|
14
|
-
pry (0.9.12.6)
|
15
|
-
coderay (~> 1.0)
|
16
|
-
method_source (~> 0.8)
|
17
|
-
slop (~> 3.4)
|
18
|
-
rake (10.3.1)
|
19
|
-
rspec (2.14.1)
|
20
|
-
rspec-core (~> 2.14.0)
|
21
|
-
rspec-expectations (~> 2.14.0)
|
22
|
-
rspec-mocks (~> 2.14.0)
|
23
|
-
rspec-core (2.14.8)
|
24
|
-
rspec-expectations (2.14.5)
|
25
|
-
diff-lcs (>= 1.1.3, < 2.0)
|
26
|
-
rspec-mocks (2.14.6)
|
27
|
-
simplecov (0.8.2)
|
28
|
-
docile (~> 1.1.0)
|
29
|
-
multi_json
|
30
|
-
simplecov-html (~> 0.8.0)
|
31
|
-
simplecov-html (0.8.0)
|
32
|
-
slop (3.5.0)
|
33
|
-
|
34
|
-
PLATFORMS
|
35
|
-
ruby
|
36
|
-
|
37
|
-
DEPENDENCIES
|
38
|
-
build_box!
|
39
|
-
bundler (~> 1.5)
|
40
|
-
pry
|
41
|
-
rake
|
42
|
-
rspec
|
43
|
-
simplecov
|