From 61eb6e9fa965ba2961506661103d5020f67edcfa Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Wed, 18 Feb 2015 14:33:24 +0100 Subject: [PATCH] When null origin is supported then credentials header must not be set. Motivation: Currently CORS can be configured to support a 'null' origin, which can be set by a browser if a resources is loaded from the local file system. When this is done 'Access-Control-Allow-Origin' will be set to "*" (any origin). There is also a configuration option to allow credentials being sent from the client (cookies, basic HTTP Authentication, client side SSL). This is indicated by the response header 'Access-Control-Allow-Credentials' being set to true. When this is set to true, the "*" origin is not valid as the value of 'Access-Control-Allow-Origin' and a browser will reject the request: http://www.w3.org/TR/cors/#resource-requests Modifications: Updated CorsHandler's setAllowCredentials to check the origin and if it is "*" then it will not add the 'Access-Control-Allow-Credentials' header. Result: Is is possible to have a client send a 'null' origin, and at the same time have configured the CORS to support that and to allow credentials in that combination. Conflicts: codec-http/src/test/java/io/netty/handler/codec/http/cors/CorsHandlerTest.java --- .../java/io/netty/handler/codec/http/cors/CorsHandler.java | 6 ++++-- .../io/netty/handler/codec/http/cors/CorsHandlerTest.java | 7 ++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/cors/CorsHandler.java b/codec-http/src/main/java/io/netty/handler/codec/http/cors/CorsHandler.java index a79c3eb8b9..69c9a53103 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/cors/CorsHandler.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/cors/CorsHandler.java @@ -40,6 +40,7 @@ import static io.netty.util.ReferenceCountUtil.*; public class CorsHandler extends ChannelHandlerAdapter { private static final InternalLogger logger = InternalLoggerFactory.getInstance(CorsHandler.class); + private static final String ANY_ORIGIN = "*"; private final CorsConfig config; private HttpRequest request; @@ -140,7 +141,7 @@ public class CorsHandler extends ChannelHandlerAdapter { } private static void setAnyOrigin(final HttpResponse response) { - setOrigin(response, "*"); + setOrigin(response, ANY_ORIGIN); } private static void setOrigin(final HttpResponse response, final CharSequence origin) { @@ -148,7 +149,8 @@ public class CorsHandler extends ChannelHandlerAdapter { } private void setAllowCredentials(final HttpResponse response) { - if (config.isCredentialsAllowed()) { + if (config.isCredentialsAllowed() + && !response.headers().get(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN).equals(ANY_ORIGIN)) { response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true"); } } diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/cors/CorsHandlerTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/cors/CorsHandlerTest.java index 7c8e818330..d3a4270b29 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/cors/CorsHandlerTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/cors/CorsHandlerTest.java @@ -164,9 +164,14 @@ public class CorsHandlerTest { @Test public void preflightRequestWithNullOrigin() { final String origin = "null"; - final CorsConfig config = CorsConfig.withOrigin(origin).allowNullOrigin().build(); + final CorsConfig config = CorsConfig.withOrigin(origin) + .allowNullOrigin() + .allowCredentials() + .build(); final HttpResponse response = preflightRequest(config, origin, "content-type, xheader1"); assertThat(response.headers().getAndConvert(ACCESS_CONTROL_ALLOW_ORIGIN), is(equalTo("*"))); + assertThat(response.headers().getAndConvert(ACCESS_CONTROL_ALLOW_ORIGIN), is(equalTo("*"))); + assertThat(response.headers().getAndConvert(ACCESS_CONTROL_ALLOW_CREDENTIALS), is(nullValue())); } @Test