当用户使用我的应用程序时,他们会在某一时刻得到一个数组数组,如下所示:
results = [["value",25], ["value2",30]...]
子阵列可能更大,并且将采用类似的格式。我想允许我的用户编写自己的自定义转换函数,它将获取一个数组数组,并返回一个数组,一个字符串或一个数字。函数应如下所示:
def user_transform_function(array_of_arrays)
# eval users code, only let them touch the array of arrays
end
是否有一种安全的方法来沙箱此功能和eval,以便用户无法尝试执行恶意代码?例如,没有Web标注,没有数据库标注等等。
答案 0 :(得分:2)
首先,如果您使用eval
,它将永远不会安全。您至少可以查看taint
方法的方向。
我建议为此创建自己的DSL。 Ruby中有一个很棒的框架:http://treetop.rubyforge.org/index.html。当然,它需要您的一些努力,但从用户的角度来看,我认为它可能会更好。
答案 1 :(得分:1)
警告:我无法保证这是真正安全的!
您可以将它作为一个单独的进程运行并使用ruby $SAFE,但这并不能保证您获得的是安全的,但这会让事情变得更加困难。
你接下来会做的是这样的事情:
script = "arr.map{|e| e+2}" #from the user.
require "json"
array = [1, 2, 3, 4]
begin
results = IO.popen("ruby -e 'require \"json\"; $SAFE=3; arr = JSON.parse(ARGV[0]); puts (#{script}).to_json' #{array.to_json}") do |io|
io.read
end
rescue Exception => e
puts "Ohh, good Sir/Mam, your script caused an error."
end
if results.include?("Insecure operation")
puts "Ohh, good Sir/Mam, you cannot do such a thing"
else
begin
a = JSON.parse(results)
results = a
rescue Exception => e
puts "Ohh, good Sir/Mam, something is wrong with the results."
puts results
end
end
conquer_the_world(results) if results.is_a?(Array)
do_not_conquer_the_world(results) unless results.is_a?(Array)
或强>
你可以这样做,它出现了:
def evaluate_user_script(script)
Thread.start {
$SAFE = 4
eval(script)
}
end
但是又一次:我不知道如何从那里获取数据。