You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2015/03/18 22:13:48 UTC

svn commit: r1667615 - in /tomcat/trunk: java/org/apache/catalina/filters/CorsFilter.java test/org/apache/catalina/filters/TestCorsFilter.java test/org/apache/catalina/filters/TesterHttpServletRequest.java

Author: markt
Date: Wed Mar 18 21:13:48 2015
New Revision: 1667615

URL: http://svn.apache.org/r1667615
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=57724
Handle the case where the UA provides an Origin header for a non-CORS request.

Modified:
    tomcat/trunk/java/org/apache/catalina/filters/CorsFilter.java
    tomcat/trunk/test/org/apache/catalina/filters/TestCorsFilter.java
    tomcat/trunk/test/org/apache/catalina/filters/TesterHttpServletRequest.java

Modified: tomcat/trunk/java/org/apache/catalina/filters/CorsFilter.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/filters/CorsFilter.java?rev=1667615&r1=1667614&r2=1667615&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/filters/CorsFilter.java (original)
+++ tomcat/trunk/java/org/apache/catalina/filters/CorsFilter.java Wed Mar 18 21:13:48 2015
@@ -620,6 +620,8 @@ public final class CorsFilter implements
                 requestType = CORSRequestType.INVALID_CORS;
             } else if (!isValidOrigin(originHeader)) {
                 requestType = CORSRequestType.INVALID_CORS;
+            } else if (isLocalOrigin(request, originHeader)) {
+                return CORSRequestType.NOT_CORS;
             } else {
                 String method = request.getMethod();
                 if (method != null) {
@@ -661,6 +663,36 @@ public final class CorsFilter implements
     }
 
 
+    private boolean isLocalOrigin(HttpServletRequest request, String origin) {
+
+        // Build scheme://host:port from request
+        StringBuilder target = new StringBuilder();
+        String scheme = request.getScheme();
+        if (scheme == null) {
+            return false;
+        } else {
+            scheme = scheme.toLowerCase(Locale.ENGLISH);
+        }
+        target.append(scheme);
+        target.append("://");
+
+        String host = request.getServerName();
+        if (host == null) {
+            return false;
+        }
+        target.append(host);
+
+        int port = request.getServerPort();
+        if ("http".equals(scheme) && port != 80 ||
+                "https".equals(scheme) && port != 443) {
+            target.append(':');
+            target.append(port);
+        }
+
+        return origin.equalsIgnoreCase(target.toString());
+    }
+
+
     /*
      * Return the lower case, trimmed value of the media type from the content
      * type.

Modified: tomcat/trunk/test/org/apache/catalina/filters/TestCorsFilter.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/filters/TestCorsFilter.java?rev=1667615&r1=1667614&r2=1667615&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/filters/TestCorsFilter.java (original)
+++ tomcat/trunk/test/org/apache/catalina/filters/TestCorsFilter.java Wed Mar 18 21:13:48 2015
@@ -520,6 +520,85 @@ public class TestCorsFilter {
                 CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue());
     }
 
+    /*
+     * Negative test, when a non-CORS request arrives, with an origin header.
+     */
+    @Test
+    public void testDoFilterSameHostWithOrigin01() throws IOException, ServletException {
+        doTestDoFilterSameHostWithOrigin01(
+                "http://localhost:8080", "http", "localhost", 8080, false);
+    }
+
+    @Test
+    public void testDoFilterSameHostWithOrigin02() throws IOException, ServletException {
+        doTestDoFilterSameHostWithOrigin01(
+                "http://localhost:8080", "https", "localhost", 8080, true);
+    }
+
+    @Test
+    public void testDoFilterSameHostWithOrigin03() throws IOException, ServletException {
+        doTestDoFilterSameHostWithOrigin01(
+                "http://localhost:8080", "http", "localhost", 8081, true);
+    }
+
+    @Test
+    public void testDoFilterSameHostWithOrigin04() throws IOException, ServletException {
+        doTestDoFilterSameHostWithOrigin01(
+                "http://localhost:8080", "http", "foo.dev.local", 8080, true);
+    }
+
+    @Test
+    public void testDoFilterSameHostWithOrigin05() throws IOException, ServletException {
+        doTestDoFilterSameHostWithOrigin01(
+                "https://localhost:8443", "https", "localhost", 8443, false);
+    }
+
+    @Test
+    public void testDoFilterSameHostWithOrigin06() throws IOException, ServletException {
+        doTestDoFilterSameHostWithOrigin01(
+                "https://localhost", "https", "localhost", 443, false);
+    }
+
+    @Test
+    public void testDoFilterSameHostWithOrigin07() throws IOException, ServletException {
+        doTestDoFilterSameHostWithOrigin01(
+                "http://localhost", "http", "localhost", 80, false);
+    }
+
+    private void doTestDoFilterSameHostWithOrigin01(String origin, String scheme, String host,
+            int port, boolean isCors) throws IOException, ServletException {
+
+        TesterHttpServletRequest request = new TesterHttpServletRequest();
+
+        request.setMethod("POST");
+        request.setHeader(CorsFilter.REQUEST_HEADER_ORIGIN, origin);
+        request.setScheme(scheme);
+        request.setServerName(host);
+        request.setServerPort(port);
+        request.setContentType("text/plain");
+        TesterHttpServletResponse response = new TesterHttpServletResponse();
+
+        CorsFilter corsFilter = new CorsFilter();
+        corsFilter.init(TesterFilterConfigs.getDefaultFilterConfig());
+        CorsFilter.CORSRequestType requestType =
+                corsFilter.checkRequestType(request);
+        if (isCors) {
+            Assert.assertNotEquals(CorsFilter.CORSRequestType.NOT_CORS, requestType);
+        } else {
+            Assert.assertEquals(CorsFilter.CORSRequestType.NOT_CORS, requestType);
+        }
+
+        corsFilter.doFilter(request, response, filterChain);
+
+        if (isCors) {
+            Assert.assertTrue(((Boolean) request.getAttribute(
+                    CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue());
+        } else {
+            Assert.assertFalse(((Boolean) request.getAttribute(
+                    CorsFilter.HTTP_REQUEST_ATTRIBUTE_IS_CORS_REQUEST)).booleanValue());
+        }
+    }
+
     @Test
     public void testDoFilterInvalidCORSOriginNotAllowed() throws IOException,
             ServletException {

Modified: tomcat/trunk/test/org/apache/catalina/filters/TesterHttpServletRequest.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/filters/TesterHttpServletRequest.java?rev=1667615&r1=1667614&r2=1667615&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/filters/TesterHttpServletRequest.java (original)
+++ tomcat/trunk/test/org/apache/catalina/filters/TesterHttpServletRequest.java Wed Mar 18 21:13:48 2015
@@ -49,6 +49,9 @@ public class TesterHttpServletRequest im
     private Map<String, Object> attributes = new HashMap<>();
     private Map<String, List<String>> headers = new HashMap<>();
     private String method;
+    private String scheme;
+    private String serverName;
+    private int serverPort;
     private String contentType;
 
     @Override
@@ -126,20 +129,30 @@ public class TesterHttpServletRequest im
 
     @Override
     public String getScheme() {
+        return scheme;
+    }
 
-        throw new RuntimeException("Not implemented");
+    public void setScheme(String scheme) {
+        this.scheme = scheme;
     }
 
     @Override
     public String getServerName() {
+        return serverName;
+    }
 
-        throw new RuntimeException("Not implemented");
+    public void setServerName(String serverName) {
+        this.serverName = serverName;
     }
 
+
     @Override
     public int getServerPort() {
+        return serverPort;
+    }
 
-        throw new RuntimeException("Not implemented");
+    public void setServerPort(int serverPort) {
+        this.serverPort = serverPort;
     }
 
     @Override
@@ -208,7 +221,6 @@ public class TesterHttpServletRequest im
 
     @Override
     public String getLocalName() {
-
         throw new RuntimeException("Not implemented");
     }
 



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