From 05647e5226193865cd7229161024312a6ca4c2d3 Mon Sep 17 00:00:00 2001 From: Sergio del Amo Date: Wed, 11 Jan 2023 17:04:18 +0100 Subject: [PATCH] fix: OK cors=true & origin and host = localhost Close #8560 --- .../tck/tests/cors/CorsSimpleRequestTest.java | 16 ++++++++++++++- .../SimpleRequestWithCorsNotEnabledTest.java | 20 ++++++++++++++++--- .../http/server/cors/CorsFilter.java | 7 +++++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/cors/CorsSimpleRequestTest.java b/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/cors/CorsSimpleRequestTest.java index 9243ba09c3e..ecec1878122 100644 --- a/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/cors/CorsSimpleRequestTest.java +++ b/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/cors/CorsSimpleRequestTest.java @@ -72,7 +72,6 @@ void corsSimpleRequestNotAllowedForLocalhostAndAny() throws IOException { (server, request) -> { RefreshCounter refreshCounter = server.getApplicationContext().getBean(RefreshCounter.class); assertEquals(0, refreshCounter.getRefreshCount()); - AssertionUtils.assertThrows(server, request, HttpResponseAssertion.builder() .status(HttpStatus.FORBIDDEN) .assertResponse(response -> assertFalse(response.getHeaders().contains("Vary"))) @@ -81,6 +80,21 @@ void corsSimpleRequestNotAllowedForLocalhostAndAny() throws IOException { }); } + @Test + void corsSimpleRequestNotAllowedForLocalhostAndOriginLocalhost() throws IOException { + asserts(SPECNAME, + Collections.singletonMap(PROPERTY_MICRONAUT_SERVER_CORS_ENABLED, StringUtils.TRUE), + createRequest("http://localhost:8000"), + (server, request) -> { + RefreshCounter refreshCounter = server.getApplicationContext().getBean(RefreshCounter.class); + assertEquals(0, refreshCounter.getRefreshCount()); + AssertionUtils.assertDoesNotThrow(server, request, HttpResponseAssertion.builder() + .status(HttpStatus.OK) + .build()); + assertEquals(1, refreshCounter.getRefreshCount()); + }); + } + /** * CORS Simple request for localhost can be allowed via configuration. * @throws IOException may throw the try for resources diff --git a/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/cors/SimpleRequestWithCorsNotEnabledTest.java b/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/cors/SimpleRequestWithCorsNotEnabledTest.java index 6ede80ac6b9..dd63689b3f4 100644 --- a/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/cors/SimpleRequestWithCorsNotEnabledTest.java +++ b/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/cors/SimpleRequestWithCorsNotEnabledTest.java @@ -53,7 +53,7 @@ public class SimpleRequestWithCorsNotEnabledTest { @Test void corsSimpleRequestNotAllowedForLocalhostAndAny() throws IOException { asserts(SPECNAME, - createRequest(), + createRequest("https://sdelamo.github.io"), (server, request) -> { RefreshCounter refreshCounter = server.getApplicationContext().getBean(RefreshCounter.class); assertEquals(0, refreshCounter.getRefreshCount()); @@ -66,7 +66,21 @@ void corsSimpleRequestNotAllowedForLocalhostAndAny() throws IOException { }); } - private static HttpRequest createRequest() { + @Test + void corsSimpleRequestAllowedForLocalhostAndOriginLocalhost() throws IOException { + asserts(SPECNAME, + createRequest("http://localhost:8000"), + (server, request) -> { + RefreshCounter refreshCounter = server.getApplicationContext().getBean(RefreshCounter.class); + assertEquals(0, refreshCounter.getRefreshCount()); + AssertionUtils.assertDoesNotThrow(server, request, HttpResponseAssertion.builder() + .status(HttpStatus.OK) + .build()); + assertEquals(1, refreshCounter.getRefreshCount()); + }); + } + + private static HttpRequest createRequest(String origin) { return HttpRequest.POST("/refresh", Collections.emptyMap()) .header("Accept", "*/*") .header("Accept-Encoding", "gzip, deflate, br") @@ -74,7 +88,7 @@ private static HttpRequest createRequest() { .header("Connection", "keep-alive") .header("Content-Length", "0") .header("Host", "localhost:8080") - .header("Origin", "https://sdelamo.github.io") + .header("Origin", origin) .header("sec-ch-ua", "\"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"108\", \"Google Chrome\";v=\"108\"") .header("sec-ch-ua-mobile", "?0") .header("sec-ch-ua-platform", "\"macOS\"") diff --git a/http-server/src/main/java/io/micronaut/http/server/cors/CorsFilter.java b/http-server/src/main/java/io/micronaut/http/server/cors/CorsFilter.java index 46bed4c3c81..55cc1ca0ca0 100644 --- a/http-server/src/main/java/io/micronaut/http/server/cors/CorsFilter.java +++ b/http-server/src/main/java/io/micronaut/http/server/cors/CorsFilter.java @@ -128,6 +128,13 @@ protected boolean shouldDenyToPreventDriveByLocalhostAttack(@NonNull CorsOriginC if (httpHostResolver == null) { return false; } + String origin = request.getHeaders().getOrigin().orElse(null); + if (origin == null) { + return false; + } + if (origin.startsWith(LOCALHOST)) { + return false; + } String host = httpHostResolver.resolve(request); return isAny(corsOriginConfiguration.getAllowedOrigins()) && host.startsWith(LOCALHOST);