366472: CrossDomainFilter accepts wildcard domains like *.example.com

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Thomas Becker 2012-01-12 17:33:52 +01:00 committed by Simone Bordet
parent cf30b19f7e
commit 30dade6b5a
2 changed files with 71 additions and 7 deletions

View File

@ -18,6 +18,8 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.Filter; import javax.servlet.Filter;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
@ -229,19 +231,34 @@ public class CrossOriginFilter implements Filter
if (origin.trim().length() == 0) if (origin.trim().length() == 0)
continue; continue;
boolean allowed = false;
for (String allowedOrigin : allowedOrigins) for (String allowedOrigin : allowedOrigins)
{ {
if (allowedOrigin.equals(origin)) if (allowedOrigin.contains("*"))
{ {
allowed = true; Matcher matcher = createMatcher(origin,allowedOrigin);
break; if (matcher.matches())
return true;
}
else if (allowedOrigin.equals(origin))
{
return true;
}
} }
} }
if (!allowed)
return false; return false;
} }
return true;
private Matcher createMatcher(String origin, String allowedOrigin)
{
String regex = parseAllowedWildcardOriginToRegex(allowedOrigin);
Pattern pattern = Pattern.compile(regex);
return pattern.matcher(origin);
}
private String parseAllowedWildcardOriginToRegex(String allowedOrigin)
{
String regex = allowedOrigin.replace(".","\\.");
return regex.replace("*",".*"); // we want to be greedy here to match multiple subdomains, thus we use .*
} }
private boolean isSimpleRequest(HttpServletRequest request) private boolean isSimpleRequest(HttpServletRequest request)

View File

@ -76,6 +76,52 @@ public class CrossOriginFilterTest
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS)); Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
} }
@Test
public void testSimpleRequestWithMatchingWildcardOrigin() throws Exception
{
FilterHolder filterHolder = new FilterHolder(new CrossOriginFilter());
String origin = "http://subdomain.example.com";
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "http://*.example.com");
tester.getContext().addFilter(filterHolder, "/*", FilterMapping.DEFAULT);
CountDownLatch latch = new CountDownLatch(1);
tester.getContext().addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
String request = "" +
"GET / HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Origin: " + origin + "\r\n" +
"\r\n";
String response = tester.getResponses(request);
Assert.assertTrue(response.contains("HTTP/1.1 200"));
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER));
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
}
@Test
public void testSimpleRequestWithMatchingWildcardOriginAndMultipleSubdomains() throws Exception
{
FilterHolder filterHolder = new FilterHolder(new CrossOriginFilter());
String origin = "http://subdomain.subdomain.example.com";
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "http://*.example.com");
tester.getContext().addFilter(filterHolder, "/*", FilterMapping.DEFAULT);
CountDownLatch latch = new CountDownLatch(1);
tester.getContext().addServlet(new ServletHolder(new ResourceServlet(latch)), "/*");
String request = "" +
"GET / HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Origin: " + origin + "\r\n" +
"\r\n";
String response = tester.getResponses(request);
Assert.assertTrue(response.contains("HTTP/1.1 200"));
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER));
Assert.assertTrue(response.contains(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER));
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
}
@Test @Test
public void testSimpleRequestWithMatchingOrigin() throws Exception public void testSimpleRequestWithMatchingOrigin() throws Exception
{ {
@ -327,6 +373,7 @@ public class CrossOriginFilterTest
public static class ResourceServlet extends HttpServlet public static class ResourceServlet extends HttpServlet
{ {
private static final long serialVersionUID = 1L;
private final CountDownLatch latch; private final CountDownLatch latch;
public ResourceServlet(CountDownLatch latch) public ResourceServlet(CountDownLatch latch)