✨
Ruby3.2.0で導入されたReDoS対策の効果を確認
Ruby3.2.0でReDoS対策が入ったということで、2022年に報告したReDoSの脆弱性で公表されたものについて効果を確認してみました。 [1] [2]
Faraday Net::HTTP adapter
encoded_body_benchmark.rb
require 'benchmark'
def attack_text(length)
text = 'charset=' + "\t" * length + "a" + "\t" * length + "a"
/\bcharset=\s*(.+?)\s*(;|$)/.match(text)
end
Benchmark.bm do |x|
x.report { attack_text(10) }
x.report { attack_text(100) }
x.report { attack_text(1000) }
x.report { attack_text(10000) }
x.report { attack_text(100000) }
end
# Ruby 3.1.2
❯ bundle exec ruby encoded_body_benchmark.rb
user system total real
0.000009 0.000000 0.000009 ( 0.000005)
0.000060 0.000000 0.000060 ( 0.000060)
0.005131 0.000001 0.005132 ( 0.005132)
0.520823 0.000839 0.521662 ( 0.521920)
54.252044 0.137403 54.389447 ( 54.445226)
# Ruby 3.2.0
❯ bundle exec ruby encoded_body_benchmark.rb
user system total real
0.000008 0.000001 0.000009 ( 0.000006)
0.000008 0.000001 0.000009 ( 0.000008)
0.000063 0.000007 0.000070 ( 0.000070)
0.000562 0.000059 0.000621 ( 0.000621)
0.005639 0.001153 0.006792 ( 0.006816)
Rack::Protection::IPSpoofing
ip_spoofing_benchmark.rb
require 'benchmark'
def attack_text(length)
("\t" * length +"\ta,a\t").split(/\s*,\s*/)
end
Benchmark.bm do |x|
x.report { attack_text(10) }
x.report { attack_text(100) }
x.report { attack_text(1000) }
x.report { attack_text(10000) }
x.report { attack_text(100000) }
end
# Ruby 3.1.2
❯ bundle exec ruby ip_spoofing_benchmark.rb
user system total real
0.000006 0.000000 0.000006 ( 0.000004)
0.000027 0.000000 0.000027 ( 0.000028)
0.002230 0.000000 0.002230 ( 0.002229)
0.219735 0.000466 0.220201 ( 0.220294)
22.132207 0.056974 22.189181 ( 22.218286)
# Ruby 3.2.0
❯ bundle exec ruby ip_spoofing_benchmark.rb
user system total real
0.000006 0.000001 0.000007 ( 0.000005)
0.000007 0.000000 0.000007 ( 0.000007)
0.000030 0.000001 0.000031 ( 0.000030)
0.000269 0.000001 0.000270 ( 0.000269)
0.002656 0.000016 0.002672 ( 0.002673)
Nokogiri (CVE-2022-24836)
PoCは非公開です。
# Ruby 3.1.2
❯ bundle exec ruby nokogiri_benchmark.rb
user system total real
0.000047 0.000020 0.000067 ( 0.000063)
0.000040 0.000001 0.000041 ( 0.000041)
0.002257 0.000016 0.002273 ( 0.002285)
0.219902 0.000521 0.220423 ( 0.220524)
22.096186 0.069899 22.166085 ( 22.181980)
# Ruby 3.2.0
❯ bundle exec ruby nokogiri_benchmark.rb
user system total real
0.000127 0.000187 0.000314 ( 0.000308)
0.000045 0.000001 0.000046 ( 0.000046)
0.000078 0.000000 0.000078 ( 0.000080)
0.000536 0.000103 0.000639 ( 0.000645)
0.005045 0.001094 0.006139 ( 0.006158)
Rack (CVE-2022-30122)
PoCは非公開です。
# Ruby 3.1.2
❯ bundle exec ruby broken_unquoted_benchmark.rb
user system total real
0.000009 0.000000 0.000009 ( 0.000006)
0.000034 0.000000 0.000034 ( 0.000034)
0.002474 0.000000 0.002474 ( 0.002474)
0.243811 0.000512 0.244323 ( 0.244369)
24.450106 0.058915 24.509021 ( 24.570598)
# Ruby 3.2.0
❯ bundle exec ruby broken_unquoted_benchmark.rb
user system total real
0.000006 0.000001 0.000007 ( 0.000006)
0.000007 0.000000 0.000007 ( 0.000006)
0.000043 0.000005 0.000048 ( 0.000048)
0.000366 0.000035 0.000401 ( 0.000403)
0.003492 0.000377 0.003869 ( 0.003870)
Rails Html Sanitizers (CVE-2022-23517)
scrub_benchmark.rb
require 'benchmark'
require 'rails-html-sanitizer'
def scrub(length)
scrubber = Rails::Html::PermitScrubber.new
scrubber.tags = ['s']
scrubber.attributes = ['mask']
mask = 'url(uu' * length
html_fragment = Loofah.fragment('<s mask="' + mask + '" id="aa">aa</s>')
html_fragment.scrub!(scrubber)
end
Benchmark.bm do |x|
x.report { scrub(10) }
x.report { scrub(100) }
x.report { scrub(1000) }
x.report { scrub(10000) }
x.report { scrub(100000) }
end
# Ruby 3.1.2
❯ bundle exec ruby scrub_benchmark.rb
user system total real
0.000219 0.000189 0.000408 ( 0.000407)
0.000327 0.000004 0.000331 ( 0.000334)
0.024247 0.000039 0.024286 ( 0.024305)
2.282625 0.005343 2.287968 ( 2.288805)
228.092186 0.567187 228.659373 (229.374108)
# Ruby 3.2.0
❯ bundle exec ruby scrub_benchmark.rb
user system total real
0.000312 0.000393 0.000705 ( 0.000702)
0.000170 0.000004 0.000174 ( 0.000173)
0.000483 0.000012 0.000495 ( 0.000496)
0.003801 0.000076 0.003877 ( 0.003876)
0.029116 0.000737 0.029853 ( 0.029881)
Rack (CVE-2022-44570)
PoCは非公開です。
# Ruby 3.1.2
❯ bundle exec ruby multipart_content_disposition_benchmark.rb
user system total real
0.000014 0.000001 0.000015 ( 0.000012)
0.000602 0.000003 0.000605 ( 0.000604)
0.050963 0.000148 0.051111 ( 0.051170)
4.976457 0.018192 4.994649 ( 5.011038)
❯ bundle exec ruby byte_range_benchnark.rb
user system total real
0.000013 0.000000 0.000013 ( 0.000011)
0.000010 0.000001 0.000011 ( 0.000010)
0.000055 0.000001 0.000056 ( 0.000055)
0.000490 0.000043 0.000533 ( 0.000533)
0.004374 0.000447 0.004821 ( 0.004826)
Rack (CVE-2022-44571)
PoCは非公開です。
# Ruby 3.1.2
❯ bundle exec ruby multipart_content_disposition_benchmark.rb
user system total real
0.000012 0.000000 0.000012 ( 0.000010)
0.000519 0.000007 0.000526 ( 0.000526)
0.048907 0.000134 0.049041 ( 0.049124)
4.828467 0.011421 4.839888 ( 4.842429)
# Ruby 3.2.0
❯ bundle exec ruby multipart_content_disposition_benchmark.rb
user system total real
0.000014 0.000000 0.000014 ( 0.000010)
0.000072 0.000000 0.000072 ( 0.000072)
0.000697 0.000081 0.000778 ( 0.000778)
0.006980 0.002688 0.009668 ( 0.009751)
Rack (CVE-2022-44572)
PoCは非公開です。
# Ruby 3.1.2
❯ bundle exec ruby rfc2183_benchmark.rb
user system total real
0.000019 0.000000 0.000019 ( 0.000018)
0.000358 0.000004 0.000362 ( 0.000374)
0.010729 0.000005 0.010734 ( 0.010737)
0.349436 0.000997 0.350433 ( 0.350911)
11.105921 0.027338 11.133259 ( 11.137913)
22.203780 0.054924 22.258704 ( 22.265718)
# Ruby 3.2.0
❯ bundle exec ruby rfc2183_benchmark.rb
user system total real
0.000018 0.000001 0.000019 ( 0.000017)
0.000371 0.000001 0.000372 ( 0.000370)
0.011043 0.000007 0.011050 ( 0.011049)
0.351671 0.001075 0.352746 ( 0.352980)
11.349351 0.031033 11.380384 ( 11.393231)
22.604759 0.055164 22.659923 ( 22.677514)
# Regexp.timeout = 1 を設定
❯ bundle exec ruby rfc2183_benchmark.rb
user system total real
0.000022 0.000002 0.000024 ( 0.000021)
0.000422 0.000001 0.000423 ( 0.000422)
0.012381 0.000041 0.012422 ( 0.012450)
0.349678 0.000886 0.350564 ( 0.352141)
rfc2183_benchmark.rb:21:in `[]': regexp match timeout (Regexp::TimeoutError)
Action Pack (CVE-2023-22792)
PoCは非公開です。
❯ bundle exec ruby cookie_host_benchmark.rb
user system total real
0.000010 0.000000 0.000010 ( 0.000008)
0.002671 0.000003 0.002674 ( 0.002687)
2.439260 0.004220 2.443480 ( 2.444101)
user system total real
0.000007 0.000004 0.000011 ( 0.000010)
0.000030 0.000001 0.000031 ( 0.000030)
0.002248 0.000006 0.002254 ( 0.002255)
0.219704 0.000269 0.219973 ( 0.220068)
21.977842 0.046066 22.023908 ( 22.034360)
❯ bundle exec ruby cookie_host_benchmark.rb
user system total real
0.000006 0.000001 0.000007 ( 0.000006)
0.000012 0.000000 0.000012 ( 0.000012)
0.000089 0.000001 0.000090 ( 0.000089)
user system total real
0.000003 0.000001 0.000004 ( 0.000003)
0.000004 0.000000 0.000004 ( 0.000004)
0.000026 0.000000 0.000026 ( 0.000026)
0.000247 0.000000 0.000247 ( 0.000247)
0.002451 0.000018 0.002469 ( 0.002469)
Active Support (CVE-2023-22796)
PoCは非公開です。
# Ruby 3.1.2
❯ bundle exec ruby underscore_benchmark.rb
user system total real
0.000011 0.000000 0.000011 ( 0.000010)
0.000119 0.000000 0.000119 ( 0.000120)
0.010398 0.000008 0.010406 ( 0.010406)
1.049821 0.002955 1.052776 ( 1.053137)
# Ruby 3.2.0
❯ bundle exec ruby underscore_benchmark.rb
user system total real
0.000012 0.000000 0.000012 ( 0.000011)
0.000108 0.000001 0.000109 ( 0.000108)
0.009456 0.000003 0.009459 ( 0.009463)
0.955143 0.001402 0.956545 ( 0.956543)
3.853790 0.007212 3.861002 ( 3.862404)
# Regexp.timeout = 1 を設定
❯ bundle exec ruby underscore_benchmark.rb
user system total real
0.000011 0.000000 0.000011 ( 0.000010)
0.000107 0.000000 0.000107 ( 0.000107)
0.009443 0.000003 0.009446 ( 0.009447)
0.955830 0.001711 0.957541 ( 0.957541)
.../active_support/inflector/methods.rb:100:in `gsub!': regexp match timeout (Regexp::TimeoutError)
GlobalID (CVE-2023-22799)
PoCは非公開です。
# Ruby 3.1.2
❯ bundle exec ruby locate_benchmark.rb
user system total real
0.000018 0.000000 0.000018 ( 0.000016)
0.000044 0.000001 0.000045 ( 0.000044)
0.003033 0.000005 0.003038 ( 0.003038)
0.309519 0.000834 0.310353 ( 0.310375)
31.824798 0.084978 31.909776 ( 31.958167)
# Ruby 3.2.0
❯ bundle exec ruby locate_benchmark.rb
user system total real
0.000018 0.000001 0.000019 ( 0.000016)
0.000016 0.000000 0.000016 ( 0.000016)
0.000070 0.000000 0.000070 ( 0.000071)
0.000617 0.000057 0.000674 ( 0.000674)
0.006024 0.000507 0.006531 ( 0.006554)
Discussion