REXML 中的 DoS 漏洞

Ruby 标准库中包含的 REXML 库存在 DoS 漏洞。所谓的“XML 实体爆炸”攻击技术可用于远程瘫痪(禁用)任何使用 REXML 解析用户提供的 XML 的应用程序。

大多数 Rails 应用程序都存在漏洞,因为 Rails 默认使用 REXML 解析用户提供的 XML。

影响

攻击者可以通过导致 REXML 解析包含递归嵌套实体的文档(例如)来造成拒绝服务

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE member [
  <!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
  <!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
  <!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
  <!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
  <!ENTITY e "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
  <!ENTITY f "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
  <!ENTITY g "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
]>
<member>
&a;
</member>

受影响的版本

1.8 系列

  • 1.8.6-p287 及所有更早版本
  • 1.8.7-p72 及所有更早版本

1.9 系列

  • 所有版本

解决方案

请下载以下猴子补丁以修复此问题。

然后修复您的应用程序,使其在使用 REXML 之前加载 rexml-expansion-fix2.rb。

require "rexml-expansion-fix2"
...
doc = REXML::Document.new(str)
...

如果您有 Rails 应用程序,请将 rexml-expansion-fix2.rb 复制到加载路径上的目录(例如 RAILS_ROOT/lib/),并将以下行放入 config/environment.rb 中。

require "rexml-expansion-fix2"

如果您的应用程序是 Rails 2.1 或更高版本,您可以简单地将 rexml-expansion-fix2.rb 复制到 RAILS_ROOT/config/initializers,它将自动被 require。

默认情况下,XML 实体扩展限制为 10000。您可以通过更改 REXML::Document.entity_expansion_limit 来更改它。例如:

REXML::Document.entity_expansion_limit = 1000

此修复程序将以 gem 的形式提供,并将在未来版本的 Rails 中使用,但用户应立即采取纠正措施。

致谢

感谢 ACROS Security 的 Luka Treiber 和 Mitja Kolsek 向 Ruby 和 Rails 安全团队披露此问题。

感谢 Rails 核心团队的 Michael Koziarski 创建了用于修复此漏洞的猴子补丁。

变更

  • 2008-08-29 18:46 +09:00 修复了摘要,以避免误导此漏洞是 Rails 特有的。
  • 2008-11-09 12:40 +09:00 修复了 猴子补丁中的一个错误