rufus-eval 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README.txt +87 -0
  2. data/lib/rufus/eval.rb +146 -0
  3. data/test/test.rb +84 -0
  4. metadata +56 -0
@@ -0,0 +1,87 @@
1
+
2
+ = rufus-eval
3
+
4
+ The gem 'rufus-eval' is providing eval_safely() and instance_eval_safely(). The "safely" qualifier comes from playing with the $SAFE level.
5
+
6
+ Hopefully in the near future, something like a sandbox will be used to eval code 'safely'... Playing with Ruby2Ruby would be another alternative. Ruby 1.9 will maybe yield a decent answer to that code security issue.
7
+
8
+ This rufus-eval currently doesn't work with JRuby (which doesn't respect the safe levels). The JRuby team is working closely with the Ruby team, so, waiting for future releases of [J]Ruby.
9
+
10
+
11
+ == getting it
12
+
13
+ sudo gem install rufus-eval
14
+
15
+ or at
16
+
17
+ http://rubyforge.org/frs/?group_id=4812
18
+
19
+
20
+ == usage
21
+
22
+ require 'rubygems'
23
+ require 'rufus/eval'
24
+
25
+ Rufus::eval_safely "5 * 5", 4
26
+ # => 25
27
+
28
+ class Toto
29
+ end
30
+
31
+ Rufus::instance_eval_safely Toto.new, "@toto_name='surf'", 4
32
+ # => Insecure: can't modify instance variable (SecurityError)
33
+
34
+ t = Rufus::eval_safely "class Toto\ndef to_s\n"ok"; end; Toto.new", 4
35
+ # => extending class prohibited (SecurityError)
36
+
37
+ # ...
38
+
39
+ The two methods provided are eval_safely and instance_eval_safely. Both take at least a string of source code and a safety level (2 to 4) as arguments.
40
+
41
+ The instance_eval_safely method takes an instance as first argument (the eval will be done in the 'context' of that instance).
42
+
43
+ The eval_safely method takes a last optional argument, usually filled with the local binding()
44
+
45
+ def my_eval_method
46
+
47
+ a = 3
48
+ b = 7
49
+
50
+ Rufus::eval_safely("a * b", 4, binding())
51
+ end
52
+
53
+
54
+ = dependencies
55
+
56
+ None.
57
+
58
+
59
+ == mailing list
60
+
61
+ On the rufus-ruby list[http://groups.google.com/group/rufus-ruby] :
62
+
63
+ http://groups.google.com/group/rufus-ruby
64
+
65
+
66
+ == issue tracker
67
+
68
+ http://rubyforge.org/tracker/?atid=18584&group_id=4812&func=browse
69
+
70
+
71
+ == source
72
+
73
+ http://rufus.rubyforge.org/svn/trunk/eval
74
+
75
+ svn checkout http://rufus.rubyforge.org/svn/trunk/eval
76
+
77
+
78
+ == author
79
+
80
+ John Mettraux, jmettraux@gmail.com
81
+ http://jmettraux.wordpress.com
82
+
83
+
84
+ == license
85
+
86
+ MIT
87
+
@@ -0,0 +1,146 @@
1
+ #
2
+ #--
3
+ # Copyright (c) 2007-2008, John Mettraux, jmettraux@gmail.com
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+ #++
23
+ #
24
+
25
+ #
26
+ # "made in Japan"
27
+ #
28
+ # john.mettraux@openwfe.org
29
+ #
30
+
31
+
32
+ module Rufus
33
+
34
+ #--
35
+ # Runs some remote code (uri) at a different $SAFE level.
36
+ #
37
+ #def OpenWFE.load_safely (uri, safe_level)
38
+ # source = ""
39
+ # source << "#\n"
40
+ # source << "# loaded from #{uri}\n"
41
+ # source << "#\n"
42
+ # source << open(uri).read
43
+ # load_eval_safely(source, safe_level)
44
+ #end
45
+ #
46
+ #
47
+ # Makes sure that a piece of Ruby code is run at certain safe level.
48
+ # Saves in a temp file that is reloaded in its own anonymous namespace.
49
+ #
50
+ # (no binding passing allowed like in the basic Kernel.eval() method).
51
+ #
52
+ #def OpenWFE.load_eval_safely (code, safe_level)
53
+ # tmpfname =
54
+ # "#{Dir.tmpdir}/"+
55
+ # "owfe_#{code.object_id}_#{Time.new.to_f}.tmp.rb"
56
+ # File.open tmpfname, "w" do |file|
57
+ # file.print code
58
+ # end
59
+ # Thread.new do
60
+ # $SAFE = safe_level
61
+ # load(tmpfname, true)
62
+ # end.join
63
+ # begin
64
+ # File.delete tmpfname
65
+ # rescue Excpetion => e
66
+ # # ignore
67
+ # end
68
+ #end
69
+ #++
70
+
71
+ #
72
+ # Runs some code within an instance's realm at a certain safety level.
73
+ #
74
+ def Rufus.instance_eval_safely (instance, code, safe_level)
75
+
76
+ return instance.instance_eval(code) if on_jruby?
77
+
78
+ code.untaint
79
+
80
+ r = nil
81
+
82
+ Thread.new do
83
+ $SAFE = safe_level
84
+ r = instance.instance_eval(code)
85
+ end.join
86
+
87
+ raise "cannot TAMPER with JRUBY_VERSION" if on_jruby?
88
+
89
+ r
90
+ end
91
+
92
+ #
93
+ # Runs an eval() call at a certain safety level.
94
+ #
95
+ def Rufus.eval_safely (code, safe_level, binding=nil)
96
+
97
+ return eval(code, binding) if on_jruby?
98
+
99
+ code.untaint
100
+
101
+ binding.taint
102
+
103
+ r = nil
104
+
105
+ Thread.new do
106
+ $SAFE = safe_level
107
+ r = eval code, binding
108
+ end.join
109
+
110
+ raise "cannot TAMPER with JRUBY_VERSION" if on_jruby?
111
+
112
+ r
113
+ end
114
+
115
+ #--
116
+ # evals "requires" at the current safe level and the rest of the code
117
+ # at the requested safety level.
118
+ #
119
+ #def OpenWFE.eval_r_safely (code, safe_level, binding=nil)
120
+ # code.untaint
121
+ # c = ""
122
+ # code.split("\n").each do |line|
123
+ # if line.match "^ *require " and not line.index(";")
124
+ # eval(line, binding)
125
+ # else
126
+ # c << line
127
+ # c << "\n"
128
+ # end
129
+ # end
130
+ # eval_safely(c, safe_level, binding)
131
+ #end
132
+ #++
133
+
134
+ protected
135
+
136
+ #
137
+ # Returns true if the JRUBY_VERSION is defined.
138
+ # (beware : something else than JRuby may have defined it).
139
+ #
140
+ def Rufus.on_jruby?
141
+
142
+ defined?(JRUBY_VERSION) != nil
143
+ end
144
+
145
+ end
146
+
@@ -0,0 +1,84 @@
1
+
2
+ #
3
+ # Testing rufus-eval
4
+ #
5
+ # John Mettraux at openwfe.org
6
+ #
7
+
8
+ require 'tempfile'
9
+
10
+ require 'test/unit'
11
+ require 'rufus/eval'
12
+
13
+
14
+ class EvalTest < Test::Unit::TestCase
15
+
16
+ #def setup
17
+ #end
18
+
19
+ #def teardown
20
+ #end
21
+
22
+ #def test_0
23
+ # assert_not_nil dotest("print ''", 4)
24
+ # assert_not_nil dotest2("print ''", 4)
25
+ # assert_nil dotest("print ''", 2)
26
+ # assert_nil dotest2("print ''", 2)
27
+ #end
28
+
29
+ def test_1
30
+
31
+ if Rufus::on_jruby?
32
+ puts
33
+ puts "skipping safe tests as JRuby doesn't support $SAFE levels..."
34
+ return
35
+ end
36
+
37
+ assert_not_nil dotest3(STDOUT, "self.print ''", 4)
38
+ assert_nil dotest3(STDOUT, "self.print ''", 2)
39
+
40
+ assert_not_nil dotest3(nil, "print ''", 4)
41
+ assert_nil dotest3(nil, "print ''", 2)
42
+ end
43
+
44
+ protected
45
+
46
+ #def dotest (code, level)
47
+ # tf = Tempfile.new "safely_test_temp.rb"
48
+ # tf.puts code
49
+ # tf.close
50
+ # e = nil
51
+ # begin
52
+ # OpenWFE::load_safely(tf.path, level)
53
+ # rescue Exception => e
54
+ # end
55
+ # File.delete(tf.path)
56
+ # e
57
+ #end
58
+
59
+ #def dotest2 (code, level)
60
+ # begin
61
+ # OpenWFE::load_eval_safely(code, level)
62
+ # rescue Exception => e
63
+ # return e
64
+ # end
65
+ # nil
66
+ #end
67
+
68
+ def dotest3 (instance, code, level)
69
+
70
+ begin
71
+ if instance
72
+ Rufus::instance_eval_safely instance, code, level
73
+ else
74
+ Rufus::eval_safely code, level
75
+ end
76
+ rescue Exception => e
77
+ return e
78
+ end
79
+
80
+ nil
81
+ end
82
+
83
+ end
84
+
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rufus-eval
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - John Mettraux
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-01-25 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: jmettraux@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.txt
24
+ files:
25
+ - lib/rufus
26
+ - lib/rufus/eval.rb
27
+ - test/test.rb
28
+ - README.txt
29
+ has_rdoc: true
30
+ homepage: http://rufus.rubyforge.org/rufus-eval
31
+ post_install_message:
32
+ rdoc_options: []
33
+
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: "0"
41
+ version:
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ version:
48
+ requirements: []
49
+
50
+ rubyforge_project:
51
+ rubygems_version: 0.9.5
52
+ signing_key:
53
+ specification_version: 2
54
+ summary: an eval method, a bit safer
55
+ test_files:
56
+ - test/test.rb