From 6db3f9872bb6ee052d2ec4aa6dbb296d4f827e81 Mon Sep 17 00:00:00 2001 From: Serhii Plyhun Date: Wed, 13 Mar 2024 15:28:10 +0100 Subject: [PATCH 1/4] SUP-14730: Use HttpOnly cookie flag --- .../gentics/mesh/auth/handler/MeshJWTAuthHandler.java | 9 ++++++--- .../gentics/mesh/auth/provider/MeshJWTAuthProvider.java | 5 ++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/common/src/main/java/com/gentics/mesh/auth/handler/MeshJWTAuthHandler.java b/common/src/main/java/com/gentics/mesh/auth/handler/MeshJWTAuthHandler.java index 263d9dfe38..b27d3f39e6 100644 --- a/common/src/main/java/com/gentics/mesh/auth/handler/MeshJWTAuthHandler.java +++ b/common/src/main/java/com/gentics/mesh/auth/handler/MeshJWTAuthHandler.java @@ -149,9 +149,12 @@ private void handleJWTAuth(RoutingContext context, boolean ignoreDecodeErrors) { if (!result.isUsingAPIKey()) { String jwtToken = authProvider.generateToken(authenticatedUser); // Remove the original cookie and set the new one - context.removeCookie(SharedKeys.TOKEN_COOKIE_KEY); - context.addCookie(Cookie.cookie(SharedKeys.TOKEN_COOKIE_KEY, jwtToken) - .setMaxAge(meshOptions.getAuthenticationOptions().getTokenExpirationTime()).setPath("/")); + context.response().removeCookie(SharedKeys.TOKEN_COOKIE_KEY); + context.response().addCookie(Cookie.cookie(SharedKeys.TOKEN_COOKIE_KEY, jwtToken) + .setHttpOnly(true) + .setSecure(meshOptions.getHttpServerOptions().isSsl() && !meshOptions.getHttpServerOptions().isHttp()) + .setMaxAge(meshOptions.getAuthenticationOptions().getTokenExpirationTime()) + .setPath("/")); } context.next(); } else { diff --git a/common/src/main/java/com/gentics/mesh/auth/provider/MeshJWTAuthProvider.java b/common/src/main/java/com/gentics/mesh/auth/provider/MeshJWTAuthProvider.java index 5ec9aea46d..53c51d1244 100644 --- a/common/src/main/java/com/gentics/mesh/auth/provider/MeshJWTAuthProvider.java +++ b/common/src/main/java/com/gentics/mesh/auth/provider/MeshJWTAuthProvider.java @@ -299,7 +299,10 @@ private User loadUserByJWT(JsonObject jwt) throws Exception { public void login(InternalActionContext ac, String username, String password, String newPassword) { String token = generateToken(username, password, newPassword); ac.addCookie(Cookie.cookie(SharedKeys.TOKEN_COOKIE_KEY, token) - .setMaxAge(meshOptions.getAuthenticationOptions().getTokenExpirationTime()).setPath("/")); + .setHttpOnly(true) + .setSecure(meshOptions.getHttpServerOptions().isSsl() && !meshOptions.getHttpServerOptions().isHttp()) + .setMaxAge(meshOptions.getAuthenticationOptions().getTokenExpirationTime()) + .setPath("/")); ac.send(new TokenResponse(token).toJson()); } From 827c1bc0af6f80d86358a7864d032c64982f43bf Mon Sep 17 00:00:00 2001 From: Serhii Plyhun Date: Wed, 13 Mar 2024 16:46:58 +0100 Subject: [PATCH 2/4] Changelog --- LTS-CHANGELOG.adoc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/LTS-CHANGELOG.adoc b/LTS-CHANGELOG.adoc index bc40106032..aad3e4a5cf 100644 --- a/LTS-CHANGELOG.adoc +++ b/LTS-CHANGELOG.adoc @@ -17,6 +17,11 @@ include::content/docs/variables.adoc-include[] The LTS changelog lists releases which are only accessible via a commercial subscription. All fixes and changes in LTS releases will be released the next minor release. Changes from LTS 1.4.x will be included in release 1.5.0. +[[v1.10.30]] +== 1.10.30 (TBD) + +icon:check[] Auth: A `HttpOnly` flag is set onto the JWT auth cookie. A `Secure` flag is set onto the JWT auth cookie, if a HTTPS-only server is started in Mesh. + [[v1.10.29]] == 1.10.29 (06.03.2024) From abc09e5bd2cf68a7ae8c50e31e9c5375b95b71ac Mon Sep 17 00:00:00 2001 From: Serhii Plyhun Date: Wed, 27 Mar 2024 11:33:43 +0100 Subject: [PATCH 3/4] Remove Secure flag due to the integration problems --- LTS-CHANGELOG.adoc | 2 +- .../com/gentics/mesh/auth/handler/MeshJWTAuthHandler.java | 1 - .../gentics/mesh/auth/provider/MeshJWTAuthProvider.java | 7 ++----- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/LTS-CHANGELOG.adoc b/LTS-CHANGELOG.adoc index aad3e4a5cf..ebeee4d61f 100644 --- a/LTS-CHANGELOG.adoc +++ b/LTS-CHANGELOG.adoc @@ -20,7 +20,7 @@ All fixes and changes in LTS releases will be released the next minor release. C [[v1.10.30]] == 1.10.30 (TBD) -icon:check[] Auth: A `HttpOnly` flag is set onto the JWT auth cookie. A `Secure` flag is set onto the JWT auth cookie, if a HTTPS-only server is started in Mesh. +icon:check[] Auth: A `HttpOnly` flag is set onto the JWT auth cookie. [[v1.10.29]] == 1.10.29 (06.03.2024) diff --git a/common/src/main/java/com/gentics/mesh/auth/handler/MeshJWTAuthHandler.java b/common/src/main/java/com/gentics/mesh/auth/handler/MeshJWTAuthHandler.java index b27d3f39e6..970805bac8 100644 --- a/common/src/main/java/com/gentics/mesh/auth/handler/MeshJWTAuthHandler.java +++ b/common/src/main/java/com/gentics/mesh/auth/handler/MeshJWTAuthHandler.java @@ -152,7 +152,6 @@ private void handleJWTAuth(RoutingContext context, boolean ignoreDecodeErrors) { context.response().removeCookie(SharedKeys.TOKEN_COOKIE_KEY); context.response().addCookie(Cookie.cookie(SharedKeys.TOKEN_COOKIE_KEY, jwtToken) .setHttpOnly(true) - .setSecure(meshOptions.getHttpServerOptions().isSsl() && !meshOptions.getHttpServerOptions().isHttp()) .setMaxAge(meshOptions.getAuthenticationOptions().getTokenExpirationTime()) .setPath("/")); } diff --git a/common/src/main/java/com/gentics/mesh/auth/provider/MeshJWTAuthProvider.java b/common/src/main/java/com/gentics/mesh/auth/provider/MeshJWTAuthProvider.java index 53c51d1244..9956d5dcfc 100644 --- a/common/src/main/java/com/gentics/mesh/auth/provider/MeshJWTAuthProvider.java +++ b/common/src/main/java/com/gentics/mesh/auth/provider/MeshJWTAuthProvider.java @@ -8,9 +8,6 @@ import javax.inject.Inject; import javax.inject.Singleton; -import com.gentics.mesh.auth.handler.MeshJWTAuthHandler; -import io.vertx.core.http.Cookie; -import io.vertx.ext.auth.authentication.AuthenticationProvider; import org.apache.commons.lang.NotImplementedException; import org.apache.commons.lang3.StringUtils; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @@ -30,13 +27,14 @@ import io.vertx.core.Future; import io.vertx.core.Handler; import io.vertx.core.Vertx; +import io.vertx.core.http.Cookie; import io.vertx.core.json.JsonObject; import io.vertx.core.logging.Logger; import io.vertx.core.logging.LoggerFactory; -import io.vertx.ext.auth.AuthProvider; import io.vertx.ext.auth.JWTOptions; import io.vertx.ext.auth.KeyStoreOptions; import io.vertx.ext.auth.User; +import io.vertx.ext.auth.authentication.AuthenticationProvider; import io.vertx.ext.auth.jwt.JWTAuth; import io.vertx.ext.auth.jwt.JWTAuthOptions; @@ -300,7 +298,6 @@ public void login(InternalActionContext ac, String username, String password, St String token = generateToken(username, password, newPassword); ac.addCookie(Cookie.cookie(SharedKeys.TOKEN_COOKIE_KEY, token) .setHttpOnly(true) - .setSecure(meshOptions.getHttpServerOptions().isSsl() && !meshOptions.getHttpServerOptions().isHttp()) .setMaxAge(meshOptions.getAuthenticationOptions().getTokenExpirationTime()) .setPath("/")); ac.send(new TokenResponse(token).toJson()); From f2c6ee29196bc4aa9fe61e88628d83c980815fa8 Mon Sep 17 00:00:00 2001 From: Serhii Plyhun Date: Wed, 27 Mar 2024 12:17:23 +0100 Subject: [PATCH 4/4] UT --- .../com/gentics/mesh/core/user/AuthenticationEndpointTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/tests-core/src/main/java/com/gentics/mesh/core/user/AuthenticationEndpointTest.java b/tests/tests-core/src/main/java/com/gentics/mesh/core/user/AuthenticationEndpointTest.java index 66c5164f34..801587c5e9 100644 --- a/tests/tests-core/src/main/java/com/gentics/mesh/core/user/AuthenticationEndpointTest.java +++ b/tests/tests-core/src/main/java/com/gentics/mesh/core/user/AuthenticationEndpointTest.java @@ -140,6 +140,7 @@ public void testBasicAuth() throws IOException { .build()).execute(); JsonObject responseBody = new JsonObject(response.body().string()); assertThat(responseBody.getString("username")).isEqualTo("admin"); + assertThat(response.header("set-cookie")).contains("HTTPOnly"); } private String base64(String input) {