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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4f8916fe0f7eddb619d61671068806e61f696fa1
4
- data.tar.gz: 0b6f84b6bce70a390a7888fff8ee0714a99af635
3
+ metadata.gz: 7ee932e6eaa693236f9ee28629c286aa91dd3788
4
+ data.tar.gz: 68f0e6cffe4e763d55a59a5406eee999e618654f
5
5
  SHA512:
6
- metadata.gz: c9bf87e8142525f5bd05de7b3dfbf659f37e4fb582b5d734d547ab98ffa919bceff801ac6bec883e82637feb1b58b662d8c233f15e5aa99ea98d0ce8cf993a81
7
- data.tar.gz: 89babefa1438bc4af2f5a8fbf9ba46674c945430046ad4eb5843e14b8be3bcc709950c995df432d436c6afbfc3e85d3ed70c032165390f40594da3149a2ca450
6
+ metadata.gz: f4327242827f1cd0e1c0d18643061133fdcc05b7275764ad9d737919df649ae8004cddce6535eb6cb85ef128217d9cbd65980f6619a131c7e93727a440eb0c81
7
+ data.tar.gz: c2d3889254677bfa8870ec4635a773d34bd7da2a089c58052971c725fe8f04f14b008aae8444a6ab97e612c4f9459c43c20662d346d6f5a05bacb7aee4245b25
data/Gemfile CHANGED
@@ -7,4 +7,5 @@ group :development, :test do
7
7
  gem 'rspec'
8
8
  gem 'simplecov', :require => false
9
9
  gem 'pry'
10
+ gem 'rake-notes'
10
11
  end
data/Rakefile CHANGED
@@ -1 +1,2 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rake/notes/rake_task'
@@ -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
- option :bad_constants, :default => [:Continuation, :Open3, :File, :Dir, :IO, :BuildBox, :Process, :Thread, :Fiber, :Gem, :Net, :ThreadGroup, :SystemExit, :SignalException, :Interrupt, :FileTest, :Signal]
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
@@ -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 = 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 = 2
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, TOPLEVEL_BINDING, "build_box")
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
- message = if const == Object
44
- "undefined local variable or method `#{method}' for main:Object"
45
- else
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
- const.send(:define_method, method) do |*args|
54
- raise NameError, message
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
- self.unbound_methods.each do |unbound|
61
- klass = unbound.first
62
- method = unbound.last
60
+ def restore_methods
61
+ self.unbound_methods.each do |unbound|
62
+ klass = unbound.first
63
+ method = unbound.last
63
64
 
64
- metaclass = class << klass; self; end
65
+ metaclass = class << klass; self; end
65
66
 
66
- metaclass.send(:define_method, method.name) do |*args|
67
- method.bind(klass).call(*args)
68
- end
67
+ metaclass.send(:define_method, method.name) do |*args|
68
+ method.bind(klass).call(*args)
69
+ end
69
70
 
70
- klass.send(:define_method, method.name) do |*args|
71
- method.bind(klass).call(*args)
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
- self.unbound_constants << Object.send(:remove_const, constant) if Object.const_defined?(constant)
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
- self.unbound_constants.each {|const| Object.const_set(const.to_s.to_sym, const) unless Object.const_defined?(const.to_s.to_sym)}
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
@@ -1,31 +1,33 @@
1
1
  class BuildBox::Response
2
2
 
3
- attr_accessor :output, :error, :old_constants
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
- # private
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
- self.old_constants = Object.constants
26
+ @old_constants = Object.constants
25
27
  end
26
28
 
27
29
  def restore_namespace
28
- (Object.constants - self.old_constants).each {|bad_constant| Object.send(:remove_const, bad_constant)}
30
+ (Object.constants - @old_constants).each {|bad_constant| Object.send(:remove_const, bad_constant)}
29
31
  end
30
32
 
31
33
 
@@ -1,3 +1,3 @@
1
1
  module BuildBox
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/lib/build_box.rb CHANGED
@@ -11,8 +11,8 @@ module BuildBox
11
11
  end
12
12
  alias :config :configure
13
13
 
14
- def perform(code)
15
- BuildBox::Response.new(code)
14
+ def perform(code, binding_context=TOPLEVEL_BINDING)
15
+ BuildBox::Response.new(code, binding_context)
16
16
  end
17
17
 
18
18
  end
@@ -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([[:Kernel, :exit]])
42
+ expect(BuildBox.config).to receive(:bad_methods).and_return([])
43
43
  expect(BuildBox.config).to receive(:bad_constants).and_return([])
44
- BuildBox.perform(['a = 1 + 1'])
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 eql("SecurityError: Insecure operation - exec")
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 eql("SecurityError: Insecure operation - exec")
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 eql("SecurityError: Insecure operation - `")
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.config).to receive(:bad_constants).at_least(:once).and_return([:Open3])
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
@@ -5,7 +5,7 @@
5
5
  #
6
6
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
7
  require 'pry'
8
- require 'simplecov'
8
+ # require 'simplecov'
9
9
  # SimpleCov.start
10
10
 
11
11
  # ENV['BUILD_BOX_ENV'] = 'test'
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.2
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-05 00:00:00.000000000 Z
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