From 4ae27d8075b2d138d13cb2b112f0ee50934b3017 Mon Sep 17 00:00:00 2001 From: Shugo Maeda Date: Wed, 21 Apr 2021 09:43:39 +0900 Subject: [PATCH] [ruby/net-ftp] Reduce resource cosumption of Net::FTP::TIME_PARSER Reported by Alexandr Savca as a DoS vulnerability, but Net::FTP is a client library and the impact of the issue is low, so I have decided to fix it as a normal issue. Based on patch by nobu. https://github.com/ruby/net-ftp/commit/a93af636f8 --- lib/net/ftp.rb | 5 +++-- test/net/ftp/test_ftp.rb | 11 +++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/net/ftp.rb b/lib/net/ftp.rb index da502129a5..3536e01ba3 100644 --- a/lib/net/ftp.rb +++ b/lib/net/ftp.rb @@ -1054,10 +1054,11 @@ module Net TIME_PARSER = ->(value, local = false) { unless /\A(?\d{4})(?\d{2})(?\d{2}) (?\d{2})(?\d{2})(?\d{2}) - (?:\.(?\d+))?/x =~ value + (?:\.(?\d{1,17}))?/x =~ value + value = value[0, 97] + "..." if value.size > 100 raise FTPProtoError, "invalid time-val: #{value}" end - usec = fractions.to_i * 10 ** (6 - fractions.to_s.size) + usec = ".#{fractions}".to_r * 1_000_000 if fractions Time.public_send(local ? :local : :utc, year, month, day, hour, min, sec, usec) } FACT_PARSERS = Hash.new(CASE_DEPENDENT_PARSER) diff --git a/test/net/ftp/test_ftp.rb b/test/net/ftp/test_ftp.rb index fb4fa78ae3..7aa80cdcb8 100644 --- a/test/net/ftp/test_ftp.rb +++ b/test/net/ftp/test_ftp.rb @@ -2509,6 +2509,17 @@ EOF end end + def test_time_parser + s = "20371231000000." + "9" * 999999999 + assert_equal(Time.utc(2037, 12, 31, 0, 0, 0, + 99999999999999999r / 100000000000), + Net::FTP::TIME_PARSER[s]) + e = assert_raise(Net::FTPProtoError) { + Net::FTP::TIME_PARSER["x" * 999999999] + } + assert_equal("invalid time-val: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...", e.message) + end + private def create_ftp_server(sleep_time = nil)