Author: markt
Date: Wed Jan  5 15:05:42 2011
New Revision: 1055482

URL: http://svn.apache.org/viewvc?rev=1055482&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=50453
Correctly handle multiple X-Forwarded-For headers

Modified:
    tomcat/trunk/java/org/apache/catalina/filters/RemoteIpFilter.java
    tomcat/trunk/java/org/apache/catalina/valves/RemoteIpValve.java
    tomcat/trunk/test/org/apache/catalina/filters/TestRemoteIpFilter.java
    tomcat/trunk/test/org/apache/catalina/valves/TestRemoteIpValve.java
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/catalina/filters/RemoteIpFilter.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/filters/RemoteIpFilter.java?rev=1055482&r1=1055481&r2=1055482&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/filters/RemoteIpFilter.java (original)
+++ tomcat/trunk/java/org/apache/catalina/filters/RemoteIpFilter.java Wed Jan  
5 15:05:42 2011
@@ -720,8 +720,17 @@ public class RemoteIpFilter implements F
             String remoteIp = null;
             // In java 6, proxiesHeaderValue should be declared as a 
java.util.Deque
             LinkedList<String> proxiesHeaderValue = new LinkedList<String>();
+            StringBuffer concatRemoteIpHeaderValue = new StringBuffer();
             
-            String[] remoteIpHeaderValue = 
commaDelimitedListToStringArray(request.getHeader(remoteIpHeader));
+            for (Enumeration<String> e = request.getHeaders(remoteIpHeader); 
e.hasMoreElements();) {
+                if (concatRemoteIpHeaderValue.length() > 0) {
+                    concatRemoteIpHeaderValue.append(", ");
+                }
+
+                concatRemoteIpHeaderValue.append(e.nextElement());
+            }
+
+            String[] remoteIpHeaderValue = 
commaDelimitedListToStringArray(concatRemoteIpHeaderValue.toString());
             int idx;
             // loop on remoteIpHeaderValue to find the first trusted remote ip 
and to build the proxies chain
             for (idx = remoteIpHeaderValue.length - 1; idx >= 0; idx--) {
@@ -782,11 +791,11 @@ public class RemoteIpFilter implements F
                 log.debug("Incoming request " + request.getRequestURI() + " 
with originalRemoteAddr '" + request.getRemoteAddr()
                         + "', originalRemoteHost='" + request.getRemoteHost() 
+ "', originalSecure='" + request.isSecure()
                         + "', originalScheme='" + request.getScheme() + "', 
original[" + remoteIpHeader + "]='"
-                        + request.getHeader(remoteIpHeader) + ", original[" + 
protocolHeader + "]='"
+                        + concatRemoteIpHeaderValue + "', original[" + 
protocolHeader + "]='"
                         + (protocolHeader == null ? null : 
request.getHeader(protocolHeader)) + "' will be seen as newRemoteAddr='"
                         + xRequest.getRemoteAddr() + "', newRemoteHost='" + 
xRequest.getRemoteHost() + "', newScheme='"
                         + xRequest.getScheme() + "', newSecure='" + 
xRequest.isSecure() + "', new[" + remoteIpHeader + "]='"
-                        + xRequest.getHeader(remoteIpHeader) + ", new[" + 
proxiesHeader + "]='" + xRequest.getHeader(proxiesHeader) + "'");
+                        + xRequest.getHeader(remoteIpHeader) + "', new[" + 
proxiesHeader + "]='" + xRequest.getHeader(proxiesHeader) + "'");
             }
             chain.doFilter(xRequest, response);
         } else {

Modified: tomcat/trunk/java/org/apache/catalina/valves/RemoteIpValve.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/RemoteIpValve.java?rev=1055482&r1=1055481&r2=1055482&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/valves/RemoteIpValve.java (original)
+++ tomcat/trunk/java/org/apache/catalina/valves/RemoteIpValve.java Wed Jan  5 
15:05:42 2011
@@ -19,6 +19,7 @@ package org.apache.catalina.valves;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -548,8 +549,17 @@ public class RemoteIpValve extends Valve
             String remoteIp = null;
             // In java 6, proxiesHeaderValue should be declared as a 
java.util.Deque
             LinkedList<String> proxiesHeaderValue = new LinkedList<String>();
+            StringBuffer concatRemoteIpHeaderValue = new StringBuffer();
             
-            String[] remoteIpHeaderValue = 
commaDelimitedListToStringArray(request.getHeader(remoteIpHeader));
+            for (Enumeration<String> e = request.getHeaders(remoteIpHeader); 
e.hasMoreElements();) {
+                if (concatRemoteIpHeaderValue.length() > 0) {
+                    concatRemoteIpHeaderValue.append(", ");
+                }
+
+                concatRemoteIpHeaderValue.append(e.nextElement());
+            }
+
+            String[] remoteIpHeaderValue = 
commaDelimitedListToStringArray(concatRemoteIpHeaderValue.toString());
             int idx;
             // loop on remoteIpHeaderValue to find the first trusted remote ip 
and to build the proxies chain
             for (idx = remoteIpHeaderValue.length - 1; idx >= 0; idx--) {

Modified: tomcat/trunk/test/org/apache/catalina/filters/TestRemoteIpFilter.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/filters/TestRemoteIpFilter.java?rev=1055482&r1=1055481&r2=1055482&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/filters/TestRemoteIpFilter.java 
(original)
+++ tomcat/trunk/test/org/apache/catalina/filters/TestRemoteIpFilter.java Wed 
Jan  5 15:05:42 2011
@@ -111,6 +111,10 @@ public class TestRemoteIpFilter extends 
             
getCoyoteRequest().getMimeHeaders().setValue(name).setString(value);
         }
 
+        public void addHeader(String name, String value) {
+            
getCoyoteRequest().getMimeHeaders().addValue(name).setString(value);
+        }
+
         public void setScheme(String scheme) {
             getCoyoteRequest().scheme().setString(scheme);
         }
@@ -250,7 +254,7 @@ public class TestRemoteIpFilter extends 
         MockHttpServletRequest request = new MockHttpServletRequest();
         request.setRemoteAddr("192.168.0.10");
         request.setRemoteHost("remote-host-original-value");
-        request.setHeader("x-forwarded-for", "140.211.11.130, 192.168.0.10, 
192.168.0.11");
+        request.addHeader("x-forwarded-for", "140.211.11.130, 192.168.0.10, 
192.168.0.11");
 
         // TEST
         HttpServletRequest actualRequest = testRemoteIpFilter(filterDef, 
request);
@@ -315,7 +319,9 @@ public class TestRemoteIpFilter extends 
         MockHttpServletRequest request = new MockHttpServletRequest();
         request.setRemoteAddr("192.168.0.10");
         request.setRemoteHost("remote-host-original-value");
-        request.setHeader("x-forwarded-for", "140.211.11.130, proxy1, proxy2");
+        request.addHeader("x-forwarded-for", "140.211.11.130");
+        request.addHeader("x-forwarded-for", "proxy1");
+        request.addHeader("x-forwarded-for", "proxy2");
 
         // TEST
         HttpServletRequest actualRequest = testRemoteIpFilter(filterDef, 
request);

Modified: tomcat/trunk/test/org/apache/catalina/valves/TestRemoteIpValve.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/valves/TestRemoteIpValve.java?rev=1055482&r1=1055481&r2=1055482&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/valves/TestRemoteIpValve.java 
(original)
+++ tomcat/trunk/test/org/apache/catalina/valves/TestRemoteIpValve.java Wed Jan 
 5 15:05:42 2011
@@ -263,7 +263,9 @@ public class TestRemoteIpValve extends T
         request.setCoyoteRequest(new org.apache.coyote.Request());
         request.setRemoteAddr("192.168.0.10");
         request.setRemoteHost("remote-host-original-value");
-        
request.getCoyoteRequest().getMimeHeaders().addValue("x-forwarded-for").setString("140.211.11.130,
 proxy1, proxy2");
+        
request.getCoyoteRequest().getMimeHeaders().addValue("x-forwarded-for").setString("140.211.11.130");
+        
request.getCoyoteRequest().getMimeHeaders().addValue("x-forwarded-for").setString("proxy1");
+        
request.getCoyoteRequest().getMimeHeaders().addValue("x-forwarded-for").setString("proxy2");
         
         // TEST
         remoteIpValve.invoke(request, null);

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1055482&r1=1055481&r2=1055482&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Wed Jan  5 15:05:42 2011
@@ -168,6 +168,11 @@
         Log a warning if context.xml files define values for properties  that 
do
         not exist (e.g. if there is a typo in a property name). (markt)
       </fix>
+      <fix>
+        <bug>50453</bug>: Correctly handle multiple 
<code>X-Forwarded-For</code>
+        headers in the RemoteIpFilter and RemoteIpValve. Patch provided by Jim
+        Riggs. (markt)
+      </fix>
       <add>
         <bug>50541</bug>: Add support for setting the size limit and time limit
         for LDAP seaches when using the JNDI Realm with 
<code>userSearch</code>.



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to