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]
