目录搜索
Ruby用户指南3、开始4、简单的例子5、字符串6、正则表达式7、数组8、回到那些简单的例子9、流程控制10、迭代器11、面向对象思维12、方法13、类14、继承15、重载方法16、访问控制17、单态方法18、模块19、过程对象20、变量21、全局变量22、实变量23、局部变量24、类常量25、异常处理:rescue26、异常处理:ensure27、存取器28、对象的初始化29、杂项RGSS入门教程1、什么是RGSS2、开始:最简单的脚本3、数据类型:数字4、数据类型:常量与变量5、数据类型:字符串6、控制语句:条件分歧语句7、控制语句:循环8、函数9、对象与类10、显示图片11、数组12、哈希表(关联数组)13、类14、数据库15、游戏对象16、精灵的管理17、窗口的管理18、活动指令19、场景类Programming Ruby的翻译Programming Ruby: The Pragmatic Programmer's Guide前言RoadmapRuby.new类,对象和变量容器Containers,块Blocks和迭代Iterators标准类型深入方法表达式Expressions异常,捕捉和抛出(已经开始,by jellen)模块基本输入输出线程和进程当遭遇挫折Ruby和它的世界Ruby和Web开发Ruby TkRuby 和微软的 Windows扩展RubyRuby语言 (by jellen)类和对象 (by jellen)Ruby安全反射Reflection内建类和方法标准库OO设计网络和Web库Windows支持内嵌文档交互式Ruby Shell支持Ruby参考手册Ruby首页卷首语Ruby的启动环境变量对象执行结束时的相关处理线程安全模型正则表达式字句构造程序变量和常数字面值操作符表达式控制结构方法调用类/方法的定义内部函数内部变量内部常数内部类/模块/异常类附加库Ruby变更记录ruby 1.6 特性ruby 1.7 特性Ruby术语集Ruby的运行平台pack模板字符串sprintf格式Marshal格式Ruby FAQRuby的陷阱
文字

安全模型

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

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

对象的污染

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

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

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

与对象的污染有关的方法

Object#taint

污染对象

Object#tainted?

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

Object#untaint

消除对象受到的污染

安全级别

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

[ruby-list:37415]

$SAFE的相关规则

  • 程序开始时$SAFE的值为0
  • 各线程在生成时继承父线程的$SAFE
  • 不能降低现有的$SAFE

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

0级

默认的安全级别。

被污染对象

  • 可从IO、环境变量或命令行参数(ARGV)中获得的字符串

    (只有环境变量PATH例外)

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

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

禁止的操作

  • 没有

1级

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

被污染对象

  • 与0级相同

禁止的操作

  • 下列以受污染字符串为参数的操作
    • Dir, IO, File、FileTest的类方法、方法
    • 使用FileTest操作符、比较文件的更新时间
    • 执行外部命令(system, exec, ``)
    • eval (参考4级的说明)
    • 加载顶层(若使用第二参数进行wrap则可以执行)
    • require
    • trap
  • 执行外部命令(只有当环境变量PATH中包含危险路径时)

2级

被污染对象

  • 与1级相同

禁止的操作

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

  • Dir.chdir Dir.chroot Dir.mkdir Dir.rmdir
  • File.chown File.chmod File.umask File.truncate File#lstat File#chmod File#chown File#delete File#unlink File#truncate File#flock 以及FileTest模块的方法
  • IO#ioctl, IO#fcntl
  • Process.fork Process.setpgid Process.setsid Process.setpriority Process.egid= Process.kill
  • 使用危险路径load
  • 以被污染字符串为参数的load(即使被wrap也不行)
  • syscall
  • exit!
  • trap

3级

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

被污染对象

  • 所有生成的对象

禁止的操作

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

  • Object#untaint

4级

执行不安全程序时等级。

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

被污染对象

  • 与3级相同。

禁止的操作

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

  • Object#taint
  • 改变顶层的定义(autoload, load, include)
  • 对既存方法的再定义
  • 改变Object类的定义
  • 改变未被污染的类和模块的定义或改变类变量
  • 改变未被污染的对象的状态
  • 改变未被污染的全局变量
  • 使用未被污染的IO及File的处理
  • 输出到IO
  • 程序的终结(exit, abort)(且out of memory也不fatal)
  • 对其他线程造成影响的Thread类的操作以及其他线程的Thread#[]
  • ObjectSpace._id2ref
  • ObjectSpace.each_object ruby 1.7 feature
  • 改变环境变量
  • srand

其他的安全级别相关信息

  • 当$SAFE = 0时才执行require
  • 若超过Level1的话,启动时会有下列不同
    • 不把环境变量RUBYLIB添加到$:之中
    • 不把当前目录添加到$:之中
    • 不处理环境变量RUBYOPT
    • 不能使用下列开关 -s -S -e -r -i -I -x (就算脚本被setgid, setuid也是如此)
    • 不会从标准输入读入程序 (就算脚本被setgid, setuid也一样)
  • 被setuid, setgid的脚本将在超过$SAFE = 1的状态下运行。
  • 在3级以上的环境中生成的Proc将会记下该时刻的安全级别。若受污染的Proc对象被call的话,它将以记忆的安全级别来运行。
  • 若受污染的Method对象被call的话,将以4级状态运行。
  • 若将受污染的字符串指定为trap/trace_var的第二参数时,将以4级状态运行ruby 1.7 feature:在 version 1.7中,若将受污染的字符串指定为第二参数而运行trap/trace_var的话,马上就会引发异常SecurityError
  • 超过4级的话,即使out of memory也不会fatal
  • 根据您安装情况的不同,Fixnum Symbol true false nil可能不会被污染。但请注意Bignum Float可能会受到污染。

实例

$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]


上一篇:下一篇: