在 Web 服务器上执行用户提供的 ruby​​ 代码 [英] Executing user-supplied ruby code on a web server

查看:20
本文介绍了在 Web 服务器上执行用户提供的 ruby​​ 代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想让我的用户创建 Ruby 脚本,这些脚本对驻留在 Web 服务器上的一些数据进行计算,然后输出结果.脚本在服务器上执行.有没有办法安全地做到这一点?

I would like to let my users create Ruby scripts that do computation on some data residing on the web server and then outputs results. The scripts are executed on the server. Is there any way to do this securely?

更具体地说,我想:

  • 限制脚本可以使用的资源(内存和cpu),并限制其运行时间
  • 限制脚本可以使用哪些核心类(例如 String、Fixnum、Float、Math 等)
  • 让脚本访问并返回数据
  • 向用户输出任何错误

是否有任何库或项目可以满足我的要求?如果不是 Ruby,也许是其他语言?

Are there any libraries or projects that do what I'm asking for? If not in Ruby, maybe some other language?

推荐答案

您可以使用空白石板"作为洁净室,并使用沙箱来设置 安全级别至 4.

You can use a "blank slate" as a clean room, and a sandbox in which to set the safe level to 4.

一个空白的对象,你已经从中剥离了所有方法:

A blank slate an object you've stripped all the methods from:

class BlankSlate

  instance_methods.each do |name|
    class_eval do
      unless name =~ /^__|^instance_eval$|^binding$|^object_id$/
        undef_method name
      end
    end
  end

end

洁净室是您评估其他代码的上下文的对象:

A clean room is an object in which context you evaluate other code:

  clean_room = BlankSlate.new

从不受信任的来源读取命令,然后清除它.除非未受污染,否则 Ruby 将拒绝在沙箱中评估字符串.

Read a command from an untrusted source, then untaint it. Unless untainted, Ruby will refuse to eval the string in a sandbox.

  command = gets
  command.untaint

现在在沙箱中执行字符串,尽可能提高安全级别.当过程结束时,$SAFE 水平将恢复正常.我们在无尘室绑定的上下文中执行命令,因此它只能看到无尘室可以看到的方法和变量(但请记住,与任何对象一样,无尘室可以看到全局景观中的任何内容).

Now execute the string in a sandbox, cranking the safe level up as high as it will go. The $SAFE level will go back to normal when the proc ends. We execute the command in the context of the clean room's binding, so that it can only see the methods and variables that the clean room can see (remember, though, that like any object, the clean room can see anything in global scape).

  result = proc do
    $SAFE = 4
    clean_room.instance_eval do
      binding
    end.eval(command)
  end.call

打印结果:

  p result

这篇关于在 Web 服务器上执行用户提供的 ruby​​ 代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆