diff --git a/orcid-core/src/main/java/org/orcid/core/web/filters/CorsFilter.java b/orcid-core/src/main/java/org/orcid/core/web/filters/CorsFilter.java index 9cf2c9b3c1b..176b536481f 100644 --- a/orcid-core/src/main/java/org/orcid/core/web/filters/CorsFilter.java +++ b/orcid-core/src/main/java/org/orcid/core/web/filters/CorsFilter.java @@ -1,6 +1,7 @@ package org.orcid.core.web.filters; import java.io.IOException; +import java.net.URISyntaxException; import javax.annotation.Resource; import javax.servlet.FilterChain; @@ -8,6 +9,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.web.filter.OncePerRequestFilter; /** @@ -18,6 +21,8 @@ public class CorsFilter extends OncePerRequestFilter { + private static Log log = LogFactory.getLog(CorsFilter.class); + @Resource CrossDomainWebManger crossDomainWebManger; @@ -28,11 +33,23 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) { // CORS "pre-flight" request response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); - if(crossDomainWebManger.allowed(request)) { - response.addHeader("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type,Accept,x-csrf-token"); - }else{ - response.addHeader("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type, Accept"); - } + + boolean allowCrossDomain = false; + + try { + allowCrossDomain = crossDomainWebManger.allowed(request); + } catch (URISyntaxException e) { + String origin = request.getHeader("origin"); + String referer = request.getHeader("referer"); + log.error("Unable to process your request due an invalid URI exception, please check your origin and request headers: origin = '" + origin + "' referer = '" + referer + "'" , e); + // Lets log the exception and assume cross domain call was rejected + } + + if(allowCrossDomain) { + response.addHeader("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type,Accept,x-csrf-token"); + } else { + response.addHeader("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type, Accept"); + } } filterChain.doFilter(request, response); } diff --git a/orcid-core/src/main/java/org/orcid/core/web/filters/CorsFilterWeb.java b/orcid-core/src/main/java/org/orcid/core/web/filters/CorsFilterWeb.java index cc82eb8e908..2f43a5e1848 100644 --- a/orcid-core/src/main/java/org/orcid/core/web/filters/CorsFilterWeb.java +++ b/orcid-core/src/main/java/org/orcid/core/web/filters/CorsFilterWeb.java @@ -1,6 +1,7 @@ package org.orcid.core.web.filters; import java.io.IOException; +import java.net.URISyntaxException; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -10,6 +11,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.orcid.core.manager.impl.OrcidUrlManager; import org.orcid.pojo.ajaxForm.PojoUtil; import org.springframework.beans.factory.annotation.Value; @@ -21,25 +24,34 @@ public class CorsFilterWeb extends OncePerRequestFilter { + private static Log log = LogFactory.getLog(CorsFilterWeb.class); + @Resource CrossDomainWebManger crossDomainWebManger; - @Value("${org.orcid.core.baseUri}") + @Value("${org.orcid.core.web.filters}") private String baseUri; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - if (crossDomainWebManger.allowed(request)) { - String origin = request.getHeader("origin"); - response.addHeader("Access-Control-Allow-Origin", origin); - response.addHeader("Access-Control-Allow-Credentials", "true"); - - if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) { - // CORS "pre-flight" request - response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); - response.addHeader("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type,Accept,Authorization,x-csrf-token,x-xsrf-token"); - return; + try { + if (crossDomainWebManger.allowed(request)) { + String origin = request.getHeader("origin"); + response.addHeader("Access-Control-Allow-Origin", origin); + response.addHeader("Access-Control-Allow-Credentials", "true"); + + if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) { + // CORS "pre-flight" request + response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); + response.addHeader("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type,Accept,Authorization,x-csrf-token,x-xsrf-token"); + return; + } } + } catch (URISyntaxException e) { + String origin = request.getHeader("origin"); + String referer = request.getHeader("referer"); + log.error("Unable to process your request due an invalid URI exception, please check your origin and request headers: origin = '" + origin + "' referer = '" + referer + "'" , e); + throw new ServletException("Unable to process your request due an invalid URI exception", e); } filterChain.doFilter(request, response); diff --git a/orcid-core/src/main/java/org/orcid/core/web/filters/CrossDomainWebManger.java b/orcid-core/src/main/java/org/orcid/core/web/filters/CrossDomainWebManger.java index 9a8d9f7ea00..0c1a4222383 100644 --- a/orcid-core/src/main/java/org/orcid/core/web/filters/CrossDomainWebManger.java +++ b/orcid-core/src/main/java/org/orcid/core/web/filters/CrossDomainWebManger.java @@ -1,6 +1,8 @@ package org.orcid.core.web.filters; import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; import java.util.List; @@ -24,7 +26,7 @@ public class CrossDomainWebManger { private List domainsRegex; - public boolean allowed(HttpServletRequest request) throws MalformedURLException { + public boolean allowed(HttpServletRequest request) throws URISyntaxException { String path = OrcidUrlManager.getPathWithoutContextPath(request); // Check origin header @@ -35,9 +37,10 @@ public boolean allowed(HttpServletRequest request) throws MalformedURLException } } else { // Check referer header for localhost - if (!PojoUtil.isEmpty(request.getHeader("referer"))) { - URL netUrl = new URL(request.getHeader("referer")); - String domain = netUrl.getHost(); + String referer = request.getHeader("referer"); + if (!PojoUtil.isEmpty(referer)) { + URI uri = new URI(request.getHeader("referer")); + String domain = uri.getHost(); if (LOCALHOST.equals(domain)) { return true; } @@ -52,9 +55,9 @@ public boolean allowed(HttpServletRequest request) throws MalformedURLException return false; } - public boolean validateDomain(String url) throws MalformedURLException { - URL netUrl = new URL(url); - String domain = netUrl.getHost(); + public boolean validateDomain(String url) throws URISyntaxException { + URI uri = new URI(url); + String domain = uri.getHost(); for (String allowedDomain : getAllowedDomainsRegex()) { if (domain.matches(allowedDomain)) { return true; @@ -76,8 +79,7 @@ private List getAllowedDomainsRegex() { } private String transformPatternIntoRegex(String domainPattern) { - String result = domainPattern.replace(".", "\\."); - return result; + return domainPattern.replace(".", "\\."); } public boolean validatePath(String path) { diff --git a/orcid-core/src/main/java/org/orcid/core/web/filters/JsonpCallbackFilterWeb.java b/orcid-core/src/main/java/org/orcid/core/web/filters/JsonpCallbackFilterWeb.java index 8705537dcbd..3e11191a4cd 100644 --- a/orcid-core/src/main/java/org/orcid/core/web/filters/JsonpCallbackFilterWeb.java +++ b/orcid-core/src/main/java/org/orcid/core/web/filters/JsonpCallbackFilterWeb.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.io.OutputStream; +import java.net.URISyntaxException; import java.util.Map; import javax.annotation.Resource; @@ -40,7 +41,19 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse Map parms = httpRequest.getParameterMap(); if (parms.containsKey("callback")) { - if(crossDomainWebManger.allowed(request)) { + + boolean allowCrossDomain = false; + + try { + allowCrossDomain = crossDomainWebManger.allowed(request); + } catch (URISyntaxException e) { + String origin = request.getHeader("origin"); + String referer = request.getHeader("referer"); + log.error("Unable to process your request due an invalid URI exception, please check your origin and request headers: origin = '" + origin + "' referer = '" + referer + "'" , e); + // Lets log the exception and assume this was rejected so it is not considered a JSONP call + } + + if(allowCrossDomain) { if (log.isDebugEnabled()) log.debug("Wrapping response with JSONP callback '" + parms.get("callback")[0] + "'"); diff --git a/orcid-core/src/test/java/org/orcid/core/web/filters/CrossDomainWebMangerTest.java b/orcid-core/src/test/java/org/orcid/core/web/filters/CrossDomainWebMangerTest.java index 7e5c3663392..2bb8c364bc1 100644 --- a/orcid-core/src/test/java/org/orcid/core/web/filters/CrossDomainWebMangerTest.java +++ b/orcid-core/src/test/java/org/orcid/core/web/filters/CrossDomainWebMangerTest.java @@ -2,8 +2,9 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; -import java.net.MalformedURLException; +import java.net.URISyntaxException; import javax.annotation.Resource; @@ -33,7 +34,7 @@ public class CrossDomainWebMangerTest { "/userStatus.jsonwhatever/test","/userStatus.json/whatever","/userStatus.jsonwhatever","/userStatus.jsonwhatever/test"}; @Test - public void testDomains() throws MalformedURLException { + public void testDomains() throws URISyntaxException { for(String allowed : allowedDomains) { assertTrue("testing: " + allowed, crossDomainWebManger.validateDomain(allowed)); } @@ -44,7 +45,7 @@ public void testDomains() throws MalformedURLException { } @Test - public void testPaths() throws MalformedURLException { + public void testPaths() throws URISyntaxException { for(String allowed : allowedPaths) { assertTrue("testing: " + allowed, crossDomainWebManger.validatePath(allowed)); } @@ -53,4 +54,9 @@ public void testPaths() throws MalformedURLException { assertFalse("Testing: " + forbidden, crossDomainWebManger.validatePath(forbidden)); } } + + @Test + public void failTest() { + fail(); + } }