安全模型

为了安全地运行CGI等程序,Ruby设置了安全结构。

Ruby的安全模型由“对象的污染”和“安全级别”构成。

对象的污染

Ruby有时会认为对象“遭到了污染”,这主要有两种用途。

第一,以不安全的输入为基础制成的对象就是“受污染”的对象,不能用作“危险操作”的参数。这主要是为了防止恶意数据导致程序作出一些意外的危险动作。

第二,可以使安全对象(未遭污染的对象)得到保护,免遭不安全对象的威胁。若安全级别为4,则对未受污染的对象进行操作时就会受到很多限制,这正体现了对于安全方面的考虑。

与对象的污染有关的方法

Object#taint

污染对象

Object#tainted?

若对象受到了污染就返回真

Object#untaint

消除对象受到的污染

安全级别

每个线程都有特有的“安全级别”。安全级别越高,操作受到的限制也就越多。线程局部变量$SAFE标明了安全级别。

[ruby-list:37415]

$SAFE的相关规则

从原则上讲,低安全等级时的限制也适用于高安全等级。例如,若某操作在1级就被禁止的话,在2级就更不可能通过了。

0级

默认的安全级别。

被污染对象

环境变量PATH比较特殊,只有当其值中含有危险路径时才会受到污染。

这时所说的危险路径是指,谁都可以变更或写入的路径。从根目录起层层检查,若包含谁都可以更改的地方的话,该路径就是危险的。

禁止的操作

1级

特指以安全程序处理不安全数据的情况。适合于用CGI等处理用户的输入。

被污染对象

禁止的操作

2级

被污染对象

禁止的操作

在1级限制的基础上,以下操作也被禁止。

3级

所有生成的对象都被污染。适于为在4级状态下运行程序提供环境。

被污染对象

禁止的操作

在2级限制的基础上,以下操作也被禁止。

4级

执行不安全程序时等级。

此时,3级时禁止的“受污染字符串的eval”却被解禁。(这是因为用eval时,所有的危险操作都已经被禁止了。)

被污染对象

禁止的操作

在3级限制(如上所述,不包括eval)的基础上,以下操作也被禁止。

其他的安全级别相关信息

实例

$SAFE级别一旦升高就不能调低了。如下所示,可以使用线程将程序的一部分置入高安全级别状态下运行。

例:

def safe(level)
  result = nil
  Thread.start {
    $SAFE = level
    result = yield
  }.join
  result
end

safe(4) { puts "hello" }    # 因为是$SAFE所以例外
puts "world"                # 外部不受影响

扩展库中的应对

[ruby-list:37407]