build_box 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|