This is an automated email from the ASF dual-hosted git repository.

rmaucher pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 8afb2d09816f0f0d40db4e22bebd7ae7c262d479
Author: opencode <[email protected]>
AuthorDate: Wed Sep 30 17:10:43 2026 +0200

    Validate the port header value in RemoteIpFilter and RemoteIpValve so that 
values outside the 1-65535 range fall back to the default server port rather 
than being applied as an invalid port
---
 .../apache/catalina/filters/RemoteIpFilter.java    |  4 ++
 java/org/apache/catalina/valves/RemoteIpValve.java |  6 ++
 .../catalina/filters/TestRemoteIpFilter.java       | 54 ++++++++++++++++++
 .../apache/catalina/valves/TestRemoteIpValve.java  | 66 ++++++++++++++++++++++
 4 files changed, 130 insertions(+)

diff --git a/java/org/apache/catalina/filters/RemoteIpFilter.java 
b/java/org/apache/catalina/filters/RemoteIpFilter.java
index 666d48e82e..1393b18a27 100644
--- a/java/org/apache/catalina/filters/RemoteIpFilter.java
+++ b/java/org/apache/catalina/filters/RemoteIpFilter.java
@@ -1107,6 +1107,10 @@ public class RemoteIpFilter extends GenericFilter {
                 } catch (NumberFormatException nfe) {
                     log.debug(sm.getString("remoteIpFilter.invalidPort", 
portHeaderValue, getPortHeader()), nfe);
                 }
+                if (port < 1 || port > 65535) {
+                    log.debug(sm.getString("remoteIpFilter.invalidPort", 
portHeaderValue, getPortHeader()));
+                    port = defaultPort;
+                }
             }
         }
         xrequest.setServerPort(port);
diff --git a/java/org/apache/catalina/valves/RemoteIpValve.java 
b/java/org/apache/catalina/valves/RemoteIpValve.java
index 641d2e3507..7f0a191928 100644
--- a/java/org/apache/catalina/valves/RemoteIpValve.java
+++ b/java/org/apache/catalina/valves/RemoteIpValve.java
@@ -867,6 +867,12 @@ public class RemoteIpValve extends ValveBase {
                         
log.debug(sm.getString("remoteIpValve.invalidPortHeader", portHeaderValue, 
portHeader), nfe);
                     }
                 }
+                if (port < 1 || port > 65535) {
+                    if (log.isDebugEnabled()) {
+                        
log.debug(sm.getString("remoteIpValve.invalidPortHeader", portHeaderValue, 
portHeader));
+                    }
+                    port = defaultPort;
+                }
             }
         }
         request.setServerPort(port);
diff --git a/test/org/apache/catalina/filters/TestRemoteIpFilter.java 
b/test/org/apache/catalina/filters/TestRemoteIpFilter.java
index d3182f2487..e87d3d3ac9 100644
--- a/test/org/apache/catalina/filters/TestRemoteIpFilter.java
+++ b/test/org/apache/catalina/filters/TestRemoteIpFilter.java
@@ -598,6 +598,60 @@ public class TestRemoteIpFilter extends TomcatBaseTest {
         Assert.assertTrue("postInvoke secure", actualSecure);
     }
 
+    @Test
+    public void testInvokeXforwardedPortOutOfRange() throws Exception {
+        // PREPARE
+        FilterDef filterDef = new FilterDef();
+        filterDef.addInitParameter("portHeader", "x-forwarded-port");
+        filterDef.addInitParameter("protocolHeader", "x-forwarded-proto");
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        // client ip
+        request.setRemoteAddr("192.168.0.10");
+        request.setRemoteHost("192.168.0.10");
+        // protocol
+        request.setSecure(false);
+        request.setServerPort(8080);
+        request.setScheme("http");
+        // port
+        request.setHeader("x-forwarded-port", "99999");
+        request.setHeader("x-forwarded-proto", "https");
+
+        // TEST
+        HttpServletRequest actualRequest = testRemoteIpFilter(filterDef, 
request).getRequest();
+
+        // VERIFY
+        int actualServerPort = actualRequest.getServerPort();
+        Assert.assertEquals("postInvoke serverPort", 443, actualServerPort);
+    }
+
+    @Test
+    public void testInvokeXforwardedPortNegative() throws Exception {
+        // PREPARE
+        FilterDef filterDef = new FilterDef();
+        filterDef.addInitParameter("portHeader", "x-forwarded-port");
+        filterDef.addInitParameter("protocolHeader", "x-forwarded-proto");
+
+        MockHttpServletRequest request = new MockHttpServletRequest();
+        // client ip
+        request.setRemoteAddr("192.168.0.10");
+        request.setRemoteHost("192.168.0.10");
+        // protocol
+        request.setSecure(false);
+        request.setServerPort(8080);
+        request.setScheme("http");
+        // port
+        request.setHeader("x-forwarded-port", "-5");
+        request.setHeader("x-forwarded-proto", "https");
+
+        // TEST
+        HttpServletRequest actualRequest = testRemoteIpFilter(filterDef, 
request).getRequest();
+
+        // VERIFY
+        int actualServerPort = actualRequest.getServerPort();
+        Assert.assertEquals("postInvoke serverPort", 443, actualServerPort);
+    }
+
     @Test
     public void testInvokeXforwardedHostAndPort() throws Exception {
         // PREPARE
diff --git a/test/org/apache/catalina/valves/TestRemoteIpValve.java 
b/test/org/apache/catalina/valves/TestRemoteIpValve.java
index ed616ec2a0..71b963df03 100644
--- a/test/org/apache/catalina/valves/TestRemoteIpValve.java
+++ b/test/org/apache/catalina/valves/TestRemoteIpValve.java
@@ -908,6 +908,72 @@ public class TestRemoteIpValve {
         Assert.assertEquals("postInvoke scheme", "http", 
actualPostInvokeScheme);
     }
 
+    @Test
+    public void testInvokeXforwardedPortOutOfRange() throws Exception {
+
+        // PREPARE
+        RemoteIpValve remoteIpValve = new RemoteIpValve();
+        remoteIpValve.setPortHeader("x-forwarded-port");
+        remoteIpValve.setProtocolHeader("x-forwarded-proto");
+        RemoteAddrAndHostTrackerValve remoteAddrAndHostTrackerValve = new 
RemoteAddrAndHostTrackerValve();
+        remoteIpValve.setNext(remoteAddrAndHostTrackerValve);
+
+        Request request = new MockRequest(new org.apache.coyote.Request());
+        // client ip
+        request.setRemoteAddr("192.168.0.10");
+        request.setRemoteHost("192.168.0.10");
+        // protocol
+        request.setSecure(false);
+        request.setServerPort(8080);
+        request.getCoyoteRequest().scheme().setString("http");
+        // port
+        
request.getCoyoteRequest().getMimeHeaders().addValue("x-forwarded-port").setString("99999");
+        
request.getCoyoteRequest().getMimeHeaders().addValue("x-forwarded-proto").setString("https");
+
+        // TEST
+        remoteIpValve.invoke(request, null);
+
+        // VERIFY
+        int actualServerPort = remoteAddrAndHostTrackerValve.getServerPort();
+        Assert.assertEquals("tracked serverPort", 443, actualServerPort);
+
+        int actualPostInvokeServerPort = request.getServerPort();
+        Assert.assertEquals("postInvoke serverPort", 8080, 
actualPostInvokeServerPort);
+    }
+
+    @Test
+    public void testInvokeXforwardedPortNegative() throws Exception {
+
+        // PREPARE
+        RemoteIpValve remoteIpValve = new RemoteIpValve();
+        remoteIpValve.setPortHeader("x-forwarded-port");
+        remoteIpValve.setProtocolHeader("x-forwarded-proto");
+        RemoteAddrAndHostTrackerValve remoteAddrAndHostTrackerValve = new 
RemoteAddrAndHostTrackerValve();
+        remoteIpValve.setNext(remoteAddrAndHostTrackerValve);
+
+        Request request = new MockRequest(new org.apache.coyote.Request());
+        // client ip
+        request.setRemoteAddr("192.168.0.10");
+        request.setRemoteHost("192.168.0.10");
+        // protocol
+        request.setSecure(false);
+        request.setServerPort(8080);
+        request.getCoyoteRequest().scheme().setString("http");
+        // port
+        
request.getCoyoteRequest().getMimeHeaders().addValue("x-forwarded-port").setString("-5");
+        
request.getCoyoteRequest().getMimeHeaders().addValue("x-forwarded-proto").setString("https");
+
+        // TEST
+        remoteIpValve.invoke(request, null);
+
+        // VERIFY
+        int actualServerPort = remoteAddrAndHostTrackerValve.getServerPort();
+        Assert.assertEquals("tracked serverPort", 443, actualServerPort);
+
+        int actualPostInvokeServerPort = request.getServerPort();
+        Assert.assertEquals("postInvoke serverPort", 8080, 
actualPostInvokeServerPort);
+    }
+
     @Test
     public void testInvokeXforwardedHostAndPort() throws Exception {
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to