异常方法可以绕过 $SAFE

Exception#to_s 方法可被用于欺骗 $SAFE 检查,这使得不受信任的代码可以修改任意字符串。

详细描述

在 Ruby 的 $SAFE 语义中,安全级别 4 用于运行不受信任的代码(例如插件)。因此,在较高的安全级别中,会禁止某些操作,以防止不受信任的代码攻击外部(受信任的)数据。

Exception#to_s 方法被发现在这方面存在问题。该方法可以欺骗安全级别机制,并破坏性地修改未污染的字符串,使其变为已污染的。有了这个,攻击者可以像这样修改任意未污染的字符串

$secret_path = "foo"

proc do
    $SAFE = 4
    Exception.new($secret_path).to_s
    $secret_path.replace "/etc/passwd"
end.call

open($secret_path) do
  ...
end

受影响的版本

幸运的是,这种攻击对 ruby 的 1.9.x 系列无效。受影响的版本仅限于:

  • Ruby 1.8.6 patchlevel 420 及所有早期版本
  • Ruby 1.8.7 patchlevel 330 及所有早期版本
  • Ruby 1.8 的开发版本 (1.8.8dev)

解决方案

请升级到较新的版本。

更新