diff --git a/java/org/apache/catalina/filters/RemoteIpFilter.java b/java/org/apache/catalina/filters/RemoteIpFilter.java index 0b86fcec876d..37fd82457f9c 100644 --- a/java/org/apache/catalina/filters/RemoteIpFilter.java +++ b/java/org/apache/catalina/filters/RemoteIpFilter.java @@ -77,7 +77,7 @@ *
  • otherwise, the ip/host is declared to be the remote ip and looping is stopped.
  • * * - *
  • If the request http header named $protocolHeader (e.g. x-forwarded-for) equals to the value of + *
  • If the request http header named $protocolHeader (e.g. x-forwarded-proto) consists only of forwards that match * protocolHeaderHttpsValue configuration parameter (default https) then request.isSecure = true, * request.scheme = https and request.serverPort = 443. Note that 443 can be overwritten with the * $httpsServerPort configuration parameter.
  • @@ -805,8 +805,9 @@ public void doFilter(HttpServletRequest request, HttpServletResponse response, F if (protocolHeader != null) { String protocolHeaderValue = request.getHeader(protocolHeader); if (protocolHeaderValue == null) { - // don't modify the secure,scheme and serverPort attributes of the request - } else if (protocolHeaderHttpsValue.equalsIgnoreCase(protocolHeaderValue)) { + // Don't modify the secure, scheme and serverPort attributes + // of the request + } else if (isForwardedProtoHeaderValueSecure(protocolHeaderValue)) { xRequest.setSecure(true); xRequest.setScheme("https"); setPorts(xRequest, httpsServerPort); @@ -850,6 +851,26 @@ public void doFilter(HttpServletRequest request, HttpServletResponse response, F } + /* + * Considers the value to be secure if it exclusively holds forwards for + * {@link #protocolHeaderHttpsValue}. + */ + private boolean isForwardedProtoHeaderValueSecure(String protocolHeaderValue) { + if (!protocolHeaderValue.contains(",")) { + return protocolHeaderHttpsValue.equalsIgnoreCase(protocolHeaderValue); + } + String[] forwardedProtocols = commaDelimitedListToStringArray(protocolHeaderValue); + if (forwardedProtocols.length == 0) { + return false; + } + for (int i = 0; i < forwardedProtocols.length; i++) { + if (!protocolHeaderHttpsValue.equalsIgnoreCase(forwardedProtocols[i])) { + return false; + } + } + return true; + } + private void setPorts(XForwardedRequest xrequest, int defaultPort) { int port = defaultPort; if (getPortHeader() != null) { diff --git a/java/org/apache/catalina/valves/RemoteIpValve.java b/java/org/apache/catalina/valves/RemoteIpValve.java index 557f1a5744ac..f82af329724b 100644 --- a/java/org/apache/catalina/valves/RemoteIpValve.java +++ b/java/org/apache/catalina/valves/RemoteIpValve.java @@ -638,7 +638,7 @@ public void invoke(Request request, Response response) throws IOException, Servl if (protocolHeader != null) { String protocolHeaderValue = request.getHeader(protocolHeader); if (protocolHeaderValue == null) { - // don't modify the secure,scheme and serverPort attributes + // Don't modify the secure, scheme and serverPort attributes // of the request } else if (isForwardedProtoHeaderValueSecure(protocolHeaderValue)) { request.setSecure(true); @@ -699,7 +699,7 @@ public void invoke(Request request, Response response) throws IOException, Servl } } - /** + /* * Considers the value to be secure if it exclusively holds forwards for * {@link #protocolHeaderHttpsValue}. */ diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index fa97cfe5ed6c..78f55d6cc58e 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -119,6 +119,11 @@ the x-forwarded-proto header. Patch provided by Tom Groot. (markt) + + Update the RemoteIpFilter to handle multiple values in the + x-forwarded-proto header. Based on a patch provided by Tom + Groot. (markt) +