Ruby3.2.0で導入されたReDoS対策の効果を確認

2022/12/26に公開約11,600字

https://techlife.cookpad.com/entry/2022/12/26/121950

Ruby3.2.0でReDoS対策が入ったということで、2022年に報告したReDoSの脆弱性で公表されたものについて効果を確認してみました。 [1] [2]

Faraday Net::HTTP adapter

https://github.com/lostisland/faraday-net_http/pull/27

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

https://github.com/sinatra/sinatra/pull/1823

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)

https://github.com/advisories/GHSA-crjr-9rc5-ghw8

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)

https://discuss.rubyonrails.org/t/cve-2022-30122-denial-of-service-vulnerability-in-rack-multipart-parsing/80729

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)

https://github.com/rails/rails-html-sanitizer/security/advisories/GHSA-5x79-w82f-gw8w
https://hackerone.com/reports/1684163

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)

https://discuss.rubyonrails.org/t/cve-2022-44570-possible-denial-of-service-vulnerability-in-racks-range-header-parsing/82125

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)

https://discuss.rubyonrails.org/t/cve-2022-44571-possible-denial-of-service-vulnerability-in-rack-content-disposition-parsing/82126

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)

https://discuss.rubyonrails.org/t/cve-2022-44572-possible-denial-of-service-vulnerability-in-racks-rfc2183-boundary-parsing/82124

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)

https://discuss.rubyonrails.org/t/cve-2023-22792-possible-redos-based-dos-vulnerability-in-action-dispatch/82115

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)

https://discuss.rubyonrails.org/t/cve-2023-22796-possible-redos-based-dos-vulnerability-in-active-supports-underscore/82116

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)

https://discuss.rubyonrails.org/t/cve-2023-22799-possible-redos-based-dos-vulnerability-in-globalid/82127

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)
脚注
  1. 2022/1/5 公開されたPoCを追記 ↩︎

  2. 2022/1/19 CVE-2022-44570, CVE-2022-44571, CVE-2022-44572, CVE-2023-22792, CVE-2023-22796, CVE-2023-22799 を追加 ↩︎

Discussion

ログインするとコメントできます