build_box 0.0.2
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 +7 -0
- data/.gitignore +19 -0
- data/.rspec +2 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +43 -0
- data/LICENSE.txt +22 -0
- data/README.md +63 -0
- data/Rakefile +1 -0
- data/build_box.gemspec +23 -0
- data/lib/build_box/config.rb +58 -0
- data/lib/build_box/options/option.rb +70 -0
- data/lib/build_box/perform.rb +84 -0
- data/lib/build_box/response.rb +32 -0
- data/lib/build_box/version.rb +3 -0
- data/lib/build_box.rb +18 -0
- data/spec/build_box_spec.rb +140 -0
- data/spec/spec_helper.rb +27 -0
- metadata +91 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4f8916fe0f7eddb619d61671068806e61f696fa1
|
4
|
+
data.tar.gz: 0b6f84b6bce70a390a7888fff8ee0714a99af635
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c9bf87e8142525f5bd05de7b3dfbf659f37e4fb582b5d734d547ab98ffa919bceff801ac6bec883e82637feb1b58b662d8c233f15e5aa99ea98d0ce8cf993a81
|
7
|
+
data.tar.gz: 89babefa1438bc4af2f5a8fbf9ba46674c945430046ad4eb5843e14b8be3bcc709950c995df432d436c6afbfc3e85d3ed70c032165390f40594da3149a2ca450
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,43 @@
|
|
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
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Rafael Vettori
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# BuildBox
|
2
|
+
|
3
|
+
BuidBolx try apply security in execution your ruby code when unknown source.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'build_box'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install build_box
|
18
|
+
|
19
|
+
## Set It Up
|
20
|
+
|
21
|
+
Remove all the bad methods and classes I can think of. But maybe you need more:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
Sandrbox.configure do |config|
|
25
|
+
config.bad_constants << :Rails
|
26
|
+
config.bad_constants << :ActiveRecord
|
27
|
+
config.timeout = 3 # default seconds by execution
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
## How To Use It
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
require 'build_box'
|
35
|
+
|
36
|
+
# good execution
|
37
|
+
result = nil
|
38
|
+
result = BuildBox.perform(' 1 + 2 ');
|
39
|
+
result.output # => 3
|
40
|
+
result.error? # => false
|
41
|
+
result.error # => nil
|
42
|
+
|
43
|
+
# bad execution
|
44
|
+
result = BuildBox.perform(' 1 + nil ');
|
45
|
+
result.output # => nil
|
46
|
+
result.error? # => true
|
47
|
+
result.error # => "exception message"
|
48
|
+
|
49
|
+
# execution should be failures
|
50
|
+
BuildBox.perform('`rm -rf /`').output # => "NameError: undefined local variable or method ``' for Kernel:Module"
|
51
|
+
BuildBox.perform('exec("rm -rf /")').output # => "NameError: undefined local variable or method `exec' for main:Object"
|
52
|
+
BuildBox.perform('Kernel.exec("rm -rf /")').output # => "NameError: undefined local variable or method `exec' for Kernel:Module"BuildBox.perform(['require "open3"']).output # => ["NameError: undefined local variable or method `require' for main:Object"]
|
53
|
+
|
54
|
+
|
55
|
+
```
|
56
|
+
|
57
|
+
## Contributing
|
58
|
+
|
59
|
+
1. Fork it ( http://github.com/<my-github-username>/build_box/fork )
|
60
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
61
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
62
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
63
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/build_box.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'build_box/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "build_box"
|
8
|
+
spec.version = BuildBox::VERSION
|
9
|
+
spec.authors = ["Rafael Vettori"]
|
10
|
+
spec.email = ["rafael.vettori@gmail.com"]
|
11
|
+
spec.summary = %q{BuidBolx try apply security in execution your ruby code when unknown source.}
|
12
|
+
spec.description = ""
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'build_box/options/option'
|
2
|
+
|
3
|
+
module BuildBox
|
4
|
+
|
5
|
+
module Config
|
6
|
+
extend self
|
7
|
+
extend Options
|
8
|
+
|
9
|
+
option :bad_methods, :default => [
|
10
|
+
[:Object, :abort],
|
11
|
+
[:Kernel, :abort],
|
12
|
+
[:Object, :autoload],
|
13
|
+
[:Kernel, :autoload],
|
14
|
+
[:Object, :autoload?],
|
15
|
+
[:Kernel, :autoload?],
|
16
|
+
[:Object, :callcc],
|
17
|
+
[:Kernel, :callcc],
|
18
|
+
[:Object, :exit],
|
19
|
+
[:Kernel, :exit],
|
20
|
+
[:Object, :exit!],
|
21
|
+
[:Kernel, :exit!],
|
22
|
+
[:Object, :at_exit],
|
23
|
+
[:Kernel, :at_exit],
|
24
|
+
[:Object, :exec],
|
25
|
+
[:Kernel, :exec],
|
26
|
+
[:Object, :fork],
|
27
|
+
[:Kernel, :fork],
|
28
|
+
[:Object, :load],
|
29
|
+
[:Kernel, :load],
|
30
|
+
[:Object, :open],
|
31
|
+
[:Kernel, :open],
|
32
|
+
[:Object, :set_trace_func],
|
33
|
+
[:Kernel, :set_trace_func],
|
34
|
+
[:Object, :spawn],
|
35
|
+
[:Kernel, :spawn],
|
36
|
+
[:Object, :syscall],
|
37
|
+
[:Kernel, :syscall],
|
38
|
+
[:Object, :system],
|
39
|
+
[:Kernel, :system],
|
40
|
+
[:Object, :test],
|
41
|
+
[:Kernel, :test],
|
42
|
+
[:Object, :remove_method],
|
43
|
+
[:Kernel, :remove_method],
|
44
|
+
[:Object, :require],
|
45
|
+
[:Kernel, :require],
|
46
|
+
[:Object, :require_relative],
|
47
|
+
[:Kernel, :require_relative],
|
48
|
+
[:Object, :undef_method],
|
49
|
+
[:Kernel, :undef_method],
|
50
|
+
[:Object, "`".to_sym],
|
51
|
+
[:Kernel, "`".to_sym],
|
52
|
+
[:Class, "`".to_sym]
|
53
|
+
]
|
54
|
+
option :bad_constants, :default => [:Continuation, :Open3, :File, :Dir, :IO, :BuildBox, :Process, :Thread, :Fiber, :Gem, :Net, :ThreadGroup, :SystemExit, :SignalException, :Interrupt, :FileTest, :Signal]
|
55
|
+
|
56
|
+
option :timeout, :default => 3
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# Shamelessly stolen from Mongoid!
|
2
|
+
module BuildBox #:nodoc
|
3
|
+
module Config
|
4
|
+
|
5
|
+
# Encapsulates logic for setting options.
|
6
|
+
module Options
|
7
|
+
|
8
|
+
# Get the defaults or initialize a new empty hash.
|
9
|
+
#
|
10
|
+
# @example Get the defaults.
|
11
|
+
# options.defaults
|
12
|
+
#
|
13
|
+
# @return [ Hash ] The default options.
|
14
|
+
def defaults
|
15
|
+
@defaults ||= {}
|
16
|
+
end
|
17
|
+
|
18
|
+
# Define a configuration option with a default.
|
19
|
+
#
|
20
|
+
# @example Define the option.
|
21
|
+
# Options.option(:persist_in_safe_mode, :default => false)
|
22
|
+
#
|
23
|
+
# @param [ Symbol ] name The name of the configuration option.
|
24
|
+
# @param [ Hash ] options Extras for the option.
|
25
|
+
#
|
26
|
+
# @option options [ Object ] :default The default value.
|
27
|
+
def option(name, options = {})
|
28
|
+
defaults[name] = settings[name] = options[:default]
|
29
|
+
|
30
|
+
class_eval <<-RUBY
|
31
|
+
def #{name}
|
32
|
+
settings[#{name.inspect}]
|
33
|
+
end
|
34
|
+
|
35
|
+
def #{name}=(value)
|
36
|
+
settings[#{name.inspect}] = value
|
37
|
+
end
|
38
|
+
|
39
|
+
def #{name}?
|
40
|
+
#{name}
|
41
|
+
end
|
42
|
+
|
43
|
+
def reset_#{name}
|
44
|
+
settings[#{name.inspect}] = defaults[#{name.inspect}]
|
45
|
+
end
|
46
|
+
RUBY
|
47
|
+
end
|
48
|
+
|
49
|
+
# Reset the configuration options to the defaults.
|
50
|
+
#
|
51
|
+
# @example Reset the configuration options.
|
52
|
+
# config.reset
|
53
|
+
#
|
54
|
+
# @return [ Hash ] The defaults.
|
55
|
+
def reset
|
56
|
+
settings.replace(defaults)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Get the settings or initialize a new empty hash.
|
60
|
+
#
|
61
|
+
# @example Get the settings.
|
62
|
+
# options.settings
|
63
|
+
#
|
64
|
+
# @return [ Hash ] The setting options.
|
65
|
+
def settings
|
66
|
+
@settings ||= {}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
class BuildBox::Perform
|
2
|
+
|
3
|
+
attr_accessor :output, :error, :code, :unbound_methods, :unbound_constants
|
4
|
+
|
5
|
+
def initialize(code)
|
6
|
+
self.unbound_methods = []
|
7
|
+
self.unbound_constants = []
|
8
|
+
self.code = code
|
9
|
+
evaluate
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def evaluate
|
15
|
+
t = Thread.new do
|
16
|
+
$SAFE = 2
|
17
|
+
begin
|
18
|
+
BuildBox.config.bad_methods.each {|meth| remove_method(meth.first, meth.last)}
|
19
|
+
BuildBox.config.bad_constants.each {|const| remove_constant(const)}
|
20
|
+
@output = eval(@code, TOPLEVEL_BINDING, "build_box")
|
21
|
+
@error = nil
|
22
|
+
rescue Exception => e
|
23
|
+
@error = "#{e.class}: #{e.to_s}"
|
24
|
+
ensure
|
25
|
+
restore_constants
|
26
|
+
restore_methods
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
timeout = t.join(BuildBox.config.timeout)
|
31
|
+
if timeout.nil?
|
32
|
+
@output = "BuildBoxError: execution expired"
|
33
|
+
@error = true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def remove_method(klass, method)
|
38
|
+
const = Object.const_get(klass.to_s)
|
39
|
+
if const.methods.include?(method) || const.instance_methods.include?(method)
|
40
|
+
self.unbound_methods << [const, const.method(method).unbind]
|
41
|
+
metaclass = class << const; self; end
|
42
|
+
|
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
|
52
|
+
|
53
|
+
const.send(:define_method, method) do |*args|
|
54
|
+
raise NameError, message
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def restore_methods
|
60
|
+
self.unbound_methods.each do |unbound|
|
61
|
+
klass = unbound.first
|
62
|
+
method = unbound.last
|
63
|
+
|
64
|
+
metaclass = class << klass; self; end
|
65
|
+
|
66
|
+
metaclass.send(:define_method, method.name) do |*args|
|
67
|
+
method.bind(klass).call(*args)
|
68
|
+
end
|
69
|
+
|
70
|
+
klass.send(:define_method, method.name) do |*args|
|
71
|
+
method.bind(klass).call(*args)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def remove_constant(constant)
|
77
|
+
self.unbound_constants << Object.send(:remove_const, constant) if Object.const_defined?(constant)
|
78
|
+
end
|
79
|
+
|
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
|
83
|
+
|
84
|
+
end # BuildBox::Perform
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class BuildBox::Response
|
2
|
+
|
3
|
+
attr_accessor :output, :error, :old_constants
|
4
|
+
|
5
|
+
def initialize(code)
|
6
|
+
evaluate(code)
|
7
|
+
end
|
8
|
+
|
9
|
+
def error?
|
10
|
+
!@error.nil?
|
11
|
+
end
|
12
|
+
|
13
|
+
# private
|
14
|
+
|
15
|
+
def evaluate(code)
|
16
|
+
preserve_namespace
|
17
|
+
result = BuildBox::Perform.new(code)
|
18
|
+
@output = result.output
|
19
|
+
@error = result.error
|
20
|
+
restore_namespace
|
21
|
+
end
|
22
|
+
|
23
|
+
def preserve_namespace
|
24
|
+
self.old_constants = Object.constants
|
25
|
+
end
|
26
|
+
|
27
|
+
def restore_namespace
|
28
|
+
(Object.constants - self.old_constants).each {|bad_constant| Object.send(:remove_const, bad_constant)}
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
end
|
data/lib/build_box.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "build_box/version"
|
2
|
+
require "build_box/config"
|
3
|
+
require "build_box/response"
|
4
|
+
require "build_box/perform"
|
5
|
+
|
6
|
+
module BuildBox
|
7
|
+
extend self
|
8
|
+
|
9
|
+
def configure
|
10
|
+
block_given? ? yield(BuildBox::Config) : BuildBox::Config
|
11
|
+
end
|
12
|
+
alias :config :configure
|
13
|
+
|
14
|
+
def perform(code)
|
15
|
+
BuildBox::Response.new(code)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "BuildBox" do
|
4
|
+
|
5
|
+
describe ".perform" do
|
6
|
+
let(:correct_code){ '3+2+1'}
|
7
|
+
let(:wrong_code){ '3+2+nil'}
|
8
|
+
|
9
|
+
it "return result object" do
|
10
|
+
expect(BuildBox.config).to receive(:bad_methods).and_return([])
|
11
|
+
expect(BuildBox.config).to receive(:bad_constants).and_return([])
|
12
|
+
result = BuildBox.perform(correct_code)
|
13
|
+
expect(result).to be_a(BuildBox::Response)
|
14
|
+
expect(result).to_not be_nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "correct code syntax" do
|
18
|
+
expect(BuildBox.config).to receive(:bad_methods).and_return([])
|
19
|
+
expect(BuildBox.config).to receive(:bad_constants).and_return([])
|
20
|
+
result = BuildBox.perform(correct_code)
|
21
|
+
expect(result.error?).to be_false
|
22
|
+
expect(result.output).to eql(6)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "wrong code syntax" do
|
26
|
+
expect(BuildBox.config).to receive(:bad_methods).and_return([])
|
27
|
+
expect(BuildBox.config).to receive(:bad_constants).and_return([])
|
28
|
+
result = BuildBox.perform(wrong_code)
|
29
|
+
expect(result.error?).to be_true
|
30
|
+
expect(result.error).to_not be_empty
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'allows constants to be used after uninitializing them' do
|
34
|
+
expect(BuildBox.config).to receive(:bad_methods).and_return([])
|
35
|
+
expect(BuildBox.config).to receive(:bad_constants).and_return([:Net])
|
36
|
+
result = BuildBox.perform(' Net.methods')
|
37
|
+
expect(result.error?).to be_true
|
38
|
+
expect(Object.const_get(:Net)).to_not raise_error
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'allows methods to be called after removing them' do
|
42
|
+
expect(BuildBox.config).to receive(:bad_methods).and_return([[:Kernel, :exit]])
|
43
|
+
expect(BuildBox.config).to receive(:bad_constants).and_return([])
|
44
|
+
BuildBox.perform(['a = 1 + 1'])
|
45
|
+
Kernel.methods.should include(:exit)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'waits timeout for perform code' do
|
49
|
+
BuildBox.config.timeout = 0.1
|
50
|
+
expect(BuildBox.config).to receive(:bad_methods).and_return([[:Kernel, :exit]])
|
51
|
+
expect(BuildBox.config).to receive(:bad_constants).and_return([])
|
52
|
+
result = BuildBox.perform('sleep 0.2')
|
53
|
+
expect(result.error?).to be_true
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'removes previous class definitions and methods between calls' do
|
57
|
+
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([])
|
58
|
+
expect(BuildBox.config).to receive(:bad_constants).at_least(:once).and_return([])
|
59
|
+
BuildBox.perform("class Foo \n def test \n 'hi' \n end \n end")
|
60
|
+
expect(BuildBox.perform('Foo.new.test').error?).to be_true
|
61
|
+
expect(BuildBox.perform('Foo.new.test').error).to eql("NameError: uninitialized constant Foo")
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'unsafe commands' do
|
65
|
+
it 'does not exit' do
|
66
|
+
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([])
|
67
|
+
expect(BuildBox.config).to receive(:bad_constants).at_least(:once).and_return([])
|
68
|
+
expect(BuildBox.perform('exit')).to be_error
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'does not exit for kernel' do
|
72
|
+
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([])
|
73
|
+
expect(BuildBox.config).to receive(:bad_constants).at_least(:once).and_return([])
|
74
|
+
expect(BuildBox.perform('Kernel.exit').error).to eql("NameError: undefined local variable or method `exit' for Kernel:Module")
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'does not exec' do
|
78
|
+
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([])
|
79
|
+
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")
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'does not exec for kernel' do
|
84
|
+
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([])
|
85
|
+
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")
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'does not `' do
|
90
|
+
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([])
|
91
|
+
expect(BuildBox.config).to receive(:bad_constants).at_least(:once).and_return([])
|
92
|
+
expect(BuildBox.perform('`ls`').error).to eql("SecurityError: Insecure operation - `")
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'does not implement File' do
|
96
|
+
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([])
|
97
|
+
expect(BuildBox.config).to receive(:bad_constants).at_least(:once).and_return([:File])
|
98
|
+
expect(BuildBox.perform('File').error).to eql("NameError: uninitialized constant File")
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'does not implement Dir' do
|
102
|
+
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([])
|
103
|
+
expect(BuildBox.config).to receive(:bad_constants).at_least(:once).and_return([:Dir])
|
104
|
+
expect(BuildBox.perform('Dir').error).to eql("NameError: uninitialized constant Dir")
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'does not implement IO' do
|
108
|
+
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([])
|
109
|
+
expect(BuildBox.config).to receive(:bad_constants).at_least(:once).and_return([:IO])
|
110
|
+
expect(BuildBox.perform('IO').error).to eql("NameError: uninitialized constant IO")
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'does not implement Open3' do
|
114
|
+
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([])
|
115
|
+
expect(BuildBox.config).to receive(:bad_constants).at_least(:once).and_return([:Open3])
|
116
|
+
expect(BuildBox.perform('Open3').error).to eql("NameError: uninitialized constant Open3")
|
117
|
+
end
|
118
|
+
|
119
|
+
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")
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'does not allow you to manually call protected BuildBox methods' do
|
126
|
+
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([])
|
127
|
+
expect(BuildBox.config).to receive(:bad_constants).at_least(:once).and_return([:BuildBox])
|
128
|
+
expect(BuildBox.perform('BuildBox.inspect').error).to eql("NameError: uninitialized constant BuildBox")
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'does not allow you to manually call children of removed classes' do
|
132
|
+
expect(BuildBox.config).to receive(:bad_methods).at_least(:once).and_return([])
|
133
|
+
expect(BuildBox.config).to receive(:bad_constants).at_least(:once).and_return([:BuildBox])
|
134
|
+
expect(BuildBox.perform('BuildBox::Config.inspect').error).to eql("NameError: uninitialized constant BuildBox")
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
end # .perform
|
139
|
+
|
140
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
require 'pry'
|
8
|
+
require 'simplecov'
|
9
|
+
# SimpleCov.start
|
10
|
+
|
11
|
+
# ENV['BUILD_BOX_ENV'] = 'test'
|
12
|
+
|
13
|
+
# Dir[File.expand_path("../../", __FILE__) + "/lib/**/*.rb"].each { |f| require f }
|
14
|
+
require File.join(File.expand_path("../../", __FILE__), "lib", "build_box")
|
15
|
+
|
16
|
+
RSpec.configure do |config|
|
17
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
18
|
+
config.run_all_when_everything_filtered = true
|
19
|
+
config.filter_run :focus
|
20
|
+
|
21
|
+
# Run specs in random order to surface order dependencies. If you find an
|
22
|
+
# order dependency and want to debug it, you can fix the order by providing
|
23
|
+
# the seed, which is printed after each run.
|
24
|
+
# --seed 1234
|
25
|
+
# config.order = 'random'
|
26
|
+
config.color_enabled = true
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: build_box
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Rafael Vettori
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-05-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: ''
|
42
|
+
email:
|
43
|
+
- rafael.vettori@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".gitignore"
|
49
|
+
- ".rspec"
|
50
|
+
- Gemfile
|
51
|
+
- Gemfile.lock
|
52
|
+
- LICENSE.txt
|
53
|
+
- README.md
|
54
|
+
- Rakefile
|
55
|
+
- build_box.gemspec
|
56
|
+
- lib/build_box.rb
|
57
|
+
- lib/build_box/config.rb
|
58
|
+
- lib/build_box/options/option.rb
|
59
|
+
- lib/build_box/perform.rb
|
60
|
+
- lib/build_box/response.rb
|
61
|
+
- lib/build_box/version.rb
|
62
|
+
- spec/build_box_spec.rb
|
63
|
+
- spec/spec_helper.rb
|
64
|
+
homepage: ''
|
65
|
+
licenses:
|
66
|
+
- MIT
|
67
|
+
metadata: {}
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
requirements: []
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 2.2.0
|
85
|
+
signing_key:
|
86
|
+
specification_version: 4
|
87
|
+
summary: BuidBolx try apply security in execution your ruby code when unknown source.
|
88
|
+
test_files:
|
89
|
+
- spec/build_box_spec.rb
|
90
|
+
- spec/spec_helper.rb
|
91
|
+
has_rdoc:
|