From 82598ae4cc79eda642039902ef328bb8f1d1e312 Mon Sep 17 00:00:00 2001 From: Oscar Cowdery Lack Date: Wed, 12 Jul 2023 17:04:17 +1000 Subject: [PATCH] Always use IP of control conn for data conn Rather than using the IP provided by the server in the response to PASV, use the IP of the server we are connected to. This is more secure since we won't connect to an arbitrary endpoint provided by the server. It also works better when the server is behind a NAT and not configured properly to provide its public IP in PASV responses. See also: https://github.com/advisories/GHSA-69rc-qfx4-h683 --- src/ftp.rs | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/src/ftp.rs b/src/ftp.rs index 7ff174c..6115b0b 100644 --- a/src/ftp.rs +++ b/src/ftp.rs @@ -264,28 +264,17 @@ impl FtpStream { .ok_or_else(|| FtpError::InvalidResponse(format!("Invalid PASV response: {}", line))) .and_then(|caps| { // If the regex matches we can be sure groups contains numbers - let (oct1, oct2, oct3, oct4) = ( - caps[1].parse::().unwrap(), - caps[2].parse::().unwrap(), - caps[3].parse::().unwrap(), - caps[4].parse::().unwrap(), - ); let (msb, lsb) = ( caps[5].parse::().unwrap(), caps[6].parse::().unwrap(), ); let port = ((msb as u16) << 8) + lsb as u16; - use std::net::{IpAddr, Ipv4Addr}; - - let ip = if (oct1, oct2, oct3, oct4) == (0, 0, 0, 0) { - self.get_ref() - .peer_addr() - .map_err(FtpError::ConnectionError)? - .ip() - } else { - IpAddr::V4(Ipv4Addr::new(oct1, oct2, oct3, oct4)) - }; + let ip = self + .get_ref() + .peer_addr() + .map_err(FtpError::ConnectionError)? + .ip(); Ok(SocketAddr::new(ip, port)) }) }