You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by co...@apache.org on 2026/09/29 08:38:27 UTC
svn commit: r1938674 - in httpd/httpd/branches/2.4.x: . modules/proxy
Author: covener
Date: Tue Sep 29 08:38:27 2026
New Revision: 1938674
Log:
Merge r1938673 from trunk:
check PASV addresses
Modified:
httpd/httpd/branches/2.4.x/ (props changed)
httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_ftp.c
Modified: httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_ftp.c
==============================================================================
--- httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_ftp.c Tue Sep 29 08:35:17 2026 (r1938673)
+++ httpd/httpd/branches/2.4.x/modules/proxy/mod_proxy_ftp.c Tue Sep 29 08:38:27 2026 (r1938674)
@@ -1502,11 +1502,24 @@ static int proxy_ftp_handler(request_rec
"%d,%d,%d,%d,%d,%d", &h3, &h2, &h1, &h0, &p1, &p0) == 6)) {
apr_sockaddr_t *pasv_addr;
+ apr_sockaddr_t *ctrl_addr;
+ char *ctrl_ip;
+ const char *pasv_host;
apr_port_t pasvport = (p1 << 8) + p0;
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01044)
"PASV contacting host %d.%d.%d.%d:%d",
h3, h2, h1, h0, pasvport);
+ /* Reject PASV redirects to a different host than the
+ * control connection peer, preventing FTP bounce attacks. */
+ pasv_host = apr_psprintf(p, "%d.%d.%d.%d", h3, h2, h1, h0);
+ if (apr_socket_addr_get(&ctrl_addr, APR_REMOTE, sock) != APR_SUCCESS
+ || apr_sockaddr_ip_get(&ctrl_ip, ctrl_addr) != APR_SUCCESS
+ || strcmp(pasv_host, ctrl_ip) != 0) {
+ return ftp_proxyerror(r, backend, HTTP_FORBIDDEN,
+ "PASV address does not match FTP server");
+ }
+
if ((rv = apr_socket_create(&data_sock, backend->addr->family,
SOCK_STREAM, 0, r->pool)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01045)
@@ -1530,8 +1543,7 @@ static int proxy_ftp_handler(request_rec
}
/* make the connection */
- err = apr_sockaddr_info_get(&pasv_addr, apr_psprintf(p, "%d.%d.%d.%d",
- h3, h2, h1, h0),
+ err = apr_sockaddr_info_get(&pasv_addr, pasv_host,
backend->addr->family, pasvport, 0, p);
if (APR_SUCCESS != err) {
return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY,