summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorYusuke Endoh <mame@ruby-lang.org>2021-07-07 11:57:15 +0900
committernagachika <nagachika@ruby-lang.org>2021-07-07 19:05:36 +0900
commitbf4d05173c7cf04d8892e4b64508ecf7902717cd (patch)
tree98156d7753fbef68455301086e6f95149b2a74b6 /lib
parent1545d4f9050d7223cdfb2cf5fca170d5828512a5 (diff)
Ignore IP addresses in PASV responses by default, and add new option use_pasv_ip
This fixes CVE-2021-31810. Reported by Alexandr Savca. Co-authored-by: Shugo Maeda <shugo@ruby-lang.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/net/ftp.rb15
1 files changed, 14 insertions, 1 deletions
diff --git a/lib/net/ftp.rb b/lib/net/ftp.rb
index 68d5375ac7..2161d30d7c 100644
--- a/lib/net/ftp.rb
+++ b/lib/net/ftp.rb
@@ -98,6 +98,10 @@ module Net
# When +true+, the connection is in passive mode. Default: +true+.
attr_accessor :passive
+ # When +true+, use the IP address in PASV responses. Otherwise, it uses
+ # the same IP address for the control connection. Default: +false+.
+ attr_accessor :use_pasv_ip
+
# When +true+, all traffic to and from the server is written
# to +$stdout+. Default: +false+.
attr_accessor :debug_mode
@@ -206,6 +210,9 @@ module Net
# handshake.
# See Net::FTP#ssl_handshake_timeout for
# details. Default: +nil+.
+ # use_pasv_ip:: When +true+, use the IP address in PASV responses.
+ # Otherwise, it uses the same IP address for the control
+ # connection. Default: +false+.
# debug_mode:: When +true+, all traffic to and from the server is
# written to +$stdout+. Default: +false+.
#
@@ -266,6 +273,7 @@ module Net
@open_timeout = options[:open_timeout]
@ssl_handshake_timeout = options[:ssl_handshake_timeout]
@read_timeout = options[:read_timeout] || 60
+ @use_pasv_ip = options[:use_pasv_ip] || false
if host
connect(host, options[:port] || FTP_PORT)
if options[:username]
@@ -1381,7 +1389,12 @@ module Net
raise FTPReplyError, resp
end
if m = /\((?<host>\d+(?:,\d+){3}),(?<port>\d+,\d+)\)/.match(resp)
- return parse_pasv_ipv4_host(m["host"]), parse_pasv_port(m["port"])
+ if @use_pasv_ip
+ host = parse_pasv_ipv4_host(m["host"])
+ else
+ host = @bare_sock.remote_address.ip_address
+ end
+ return host, parse_pasv_port(m["port"])
else
raise FTPProtoError, resp
end