Avoid rejecting same-origin requests detected as CORS requests

Browsers like Chrome or Safari include an Origin header for same-origin
POST/PUT/DELETE requests, not only for cross-origin requests.

Before this commit, these same-origin requests would have been detected
as potential cross-origin requests, and rejected if the same-origin domain
is not part of the configured allowedOrigins.

This commit avoid to reject same-origin requests by reusing the logic
introduced in Spring 4.1 for detecting reliably Websocket/SockJS
same-origin requests with the WebUtils.isValidOrigin() method. This
logic has been extracted in a new WebUtils.isSameOrigin() method.

Issue: SPR-13206
This commit is contained in:
Sebastien Deleuze
2015-07-13 10:59:19 +02:00
parent 882fe129f3
commit 84138abfd1
3 changed files with 57 additions and 28 deletions

View File

@@ -106,37 +106,36 @@ public class WebUtilsTests {
}
@Test
public void isValidOriginSuccess() {
public void isValidOrigin() {
List<String> allowed = Collections.emptyList();
assertTrue(checkOrigin("mydomain1.com", -1, "http://mydomain1.com", allowed));
assertTrue(checkOrigin("mydomain1.com", -1, "http://mydomain1.com:80", allowed));
assertTrue(checkOrigin("mydomain1.com", 443, "https://mydomain1.com", allowed));
assertTrue(checkOrigin("mydomain1.com", 443, "https://mydomain1.com:443", allowed));
assertTrue(checkOrigin("mydomain1.com", 123, "http://mydomain1.com:123", allowed));
assertTrue(checkOrigin("mydomain1.com", -1, "ws://mydomain1.com", allowed));
assertTrue(checkOrigin("mydomain1.com", 443, "wss://mydomain1.com", allowed));
assertTrue(checkValidOrigin("mydomain1.com", -1, "http://mydomain1.com", allowed));
assertFalse(checkValidOrigin("mydomain1.com", -1, "http://mydomain2.com", allowed));
allowed = Collections.singletonList("*");
assertTrue(checkOrigin("mydomain1.com", -1, "http://mydomain2.com", allowed));
assertTrue(checkValidOrigin("mydomain1.com", -1, "http://mydomain2.com", allowed));
allowed = Collections.singletonList("http://mydomain1.com");
assertTrue(checkOrigin("mydomain2.com", -1, "http://mydomain1.com", allowed));
assertTrue(checkValidOrigin("mydomain2.com", -1, "http://mydomain1.com", allowed));
assertFalse(checkValidOrigin("mydomain2.com", -1, "http://mydomain3.com", allowed));
}
@Test
public void isValidOriginFailure() {
public void isSameOrigin() {
assertTrue(checkSameOrigin("mydomain1.com", -1, "http://mydomain1.com"));
assertTrue(checkSameOrigin("mydomain1.com", -1, "http://mydomain1.com:80"));
assertTrue(checkSameOrigin("mydomain1.com", 443, "https://mydomain1.com"));
assertTrue(checkSameOrigin("mydomain1.com", 443, "https://mydomain1.com:443"));
assertTrue(checkSameOrigin("mydomain1.com", 123, "http://mydomain1.com:123"));
assertTrue(checkSameOrigin("mydomain1.com", -1, "ws://mydomain1.com"));
assertTrue(checkSameOrigin("mydomain1.com", 443, "wss://mydomain1.com"));
List<String> allowed = Collections.emptyList();
assertFalse(checkOrigin("mydomain1.com", -1, "http://mydomain2.com", allowed));
assertFalse(checkOrigin("mydomain1.com", -1, "https://mydomain1.com", allowed));
assertFalse(checkOrigin("mydomain1.com", -1, "invalid-origin", allowed));
allowed = Collections.singletonList("http://mydomain1.com");
assertFalse(checkOrigin("mydomain2.com", -1, "http://mydomain3.com", allowed));
assertFalse(checkSameOrigin("mydomain1.com", -1, "http://mydomain2.com"));
assertFalse(checkSameOrigin("mydomain1.com", -1, "https://mydomain1.com"));
assertFalse(checkSameOrigin("mydomain1.com", -1, "invalid-origin"));
}
private boolean checkOrigin(String serverName, int port, String originHeader, List<String> allowed) {
private boolean checkValidOrigin(String serverName, int port, String originHeader, List<String> allowed) {
MockHttpServletRequest servletRequest = new MockHttpServletRequest();
ServerHttpRequest request = new ServletServerHttpRequest(servletRequest);
servletRequest.setServerName(serverName);
@@ -147,4 +146,15 @@ public class WebUtilsTests {
return WebUtils.isValidOrigin(request, allowed);
}
private boolean checkSameOrigin(String serverName, int port, String originHeader) {
MockHttpServletRequest servletRequest = new MockHttpServletRequest();
ServerHttpRequest request = new ServletServerHttpRequest(servletRequest);
servletRequest.setServerName(serverName);
if (port != -1) {
servletRequest.setServerPort(port);
}
request.getHeaders().set(HttpHeaders.ORIGIN, originHeader);
return WebUtils.isSameOrigin(request);
}
}