目录 搜索
Ruby用户指南 3、开始 4、简单的例子 5、字符串 6、正则表达式 7、数组 8、回到那些简单的例子 9、流程控制 10、迭代器 11、面向对象思维 12、方法 13、类 14、继承 15、重载方法 16、访问控制 17、单态方法 18、模块 19、过程对象 20、变量 21、全局变量 22、实变量 23、局部变量 24、类常量 25、异常处理:rescue 26、异常处理:ensure 27、存取器 28、对象的初始化 29、杂项 RGSS入门教程 1、什么是RGSS 2、开始:最简单的脚本 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 前言 Roadmap Ruby.new 类,对象和变量 容器Containers,块Blocks和迭代Iterators 标准类型 深入方法 表达式Expressions 异常,捕捉和抛出(已经开始,by jellen) 模块 基本输入输出 线程和进程 当遭遇挫折 Ruby和它的世界 Ruby和Web开发 Ruby Tk Ruby 和微软的 Windows 扩展Ruby Ruby语言 (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 FAQ Ruby的陷阱
文字

安全模型

为了安全地运行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]


上一篇: 下一篇: