Set SameSite for all cookies (#28467)

Closes #28465

Signed-off-by: stianst <stianst@gmail.com>
This commit is contained in:
Stian Thorgersen 2024-04-09 12:29:19 +02:00 committed by GitHub
parent 9afe3a2560
commit a499512f35
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 27 additions and 10 deletions

View file

@ -11,6 +11,20 @@ better security, with almost the same CPU time as previous releases of {project_
memory, which is a requirement to be resistant against GPU attacks. The defaults for Argon2 in {project_name} requires 7MB
per-hashing request.
= SameSite attribute set for all cookies
The following cookies did not use to set the `SameSite` attribute, which in recent browser versions results in them
defaulting to `SameSite=Lax`:
* `KC_STATE_CHECKER` now sets `SameSite=Strict`
* `KC_RESTART` now sets `SameSite=None`
* `KC_AUTH_STATE` now sets `SameSite=Strict`
* `KEYCLOAK_LOCALE` now sets `SameSite=None`
* `KEYCLOAK_REMEMBER_ME` now sets `SameSite=None`
The default value `SameSite=Lax` causes issues with POST based bindings, mostly applicable to SAML, but also used in
some OpenID Connect / OAuth 2.0 flows.
= Deprecated cookie methods removed
The following methods for setting custom cookies have been removed:

View file

@ -6,6 +6,9 @@ public enum CookieScope {
// Internal cookies are only available for direct requests to Keycloak
INTERNAL(NewCookie.SameSite.STRICT, true),
// Internal cookies that are also available from JavaScript
INTERNAL_JS(NewCookie.SameSite.STRICT, false),
// Federation cookies are available after redirect from applications, and are also available in an iframe context
// unless the browser blocks third-party cookies
FEDERATION(NewCookie.SameSite.NONE, true),

View file

@ -5,11 +5,11 @@ import jakarta.annotation.Nullable;
public final class CookieType {
public static final CookieType AUTH_DETACHED = CookieType.create("KC_STATE_CHECKER")
.scope(CookieScope.LEGACY)
.scope(CookieScope.INTERNAL)
.build();
public static final CookieType AUTH_RESTART = CookieType.create("KC_RESTART")
.scope(CookieScope.LEGACY)
.scope(CookieScope.FEDERATION)
.defaultMaxAge(CookieMaxAge.SESSION)
.build();
@ -20,7 +20,7 @@ public final class CookieType {
.build();
public static final CookieType AUTH_STATE = CookieType.create("KC_AUTH_STATE")
.scope(CookieScope.LEGACY_JS)
.scope(CookieScope.INTERNAL_JS)
.build();
public static final CookieType IDENTITY = CookieType.create("KEYCLOAK_IDENTITY")
@ -29,12 +29,12 @@ public final class CookieType {
.build();
public static final CookieType LOCALE = CookieType.create("KEYCLOAK_LOCALE")
.scope(CookieScope.LEGACY)
.scope(CookieScope.FEDERATION)
.defaultMaxAge(CookieMaxAge.SESSION)
.build();
public static final CookieType LOGIN_HINT = CookieType.create("KEYCLOAK_REMEMBER_ME")
.scope(CookieScope.LEGACY)
.scope(CookieScope.FEDERATION)
.defaultMaxAge(CookieMaxAge.YEAR)
.build();

View file

@ -53,12 +53,12 @@ public class DefaultCookieProviderTest extends AbstractKeycloakTest {
});
Assert.assertEquals(12, response.getCookies().size());
assertCookie(response, "AUTH_SESSION_ID", "my-auth-session-id", "/auth/realms/master/", -1, false, true, "None", true);
assertCookie(response, "KC_AUTH_STATE", "my-auth-state", "/auth/realms/master/", 111, false, false, null, false);
assertCookie(response, "KC_RESTART", "my-auth-restart", "/auth/realms/master/", -1, false, true, null, false);
assertCookie(response, "KC_STATE_CHECKER", "my-auth-detached", "/auth/realms/master/", 222, false, true, null, false);
assertCookie(response, "KC_AUTH_STATE", "my-auth-state", "/auth/realms/master/", 111, false, false, "Strict", false);
assertCookie(response, "KC_RESTART", "my-auth-restart", "/auth/realms/master/", -1, false, true, "None", false);
assertCookie(response, "KC_STATE_CHECKER", "my-auth-detached", "/auth/realms/master/", 222, false, true, "Strict", false);
assertCookie(response, "KEYCLOAK_IDENTITY", "my-identity", "/auth/realms/master/", 333, false, true, "None", true);
assertCookie(response, "KEYCLOAK_LOCALE", "my-locale", "/auth/realms/master/", -1, false, true, null, false);
assertCookie(response, "KEYCLOAK_REMEMBER_ME", "my-username", "/auth/realms/master/", 31536000, false, true, null, false);
assertCookie(response, "KEYCLOAK_LOCALE", "my-locale", "/auth/realms/master/", -1, false, true, "None", false);
assertCookie(response, "KEYCLOAK_REMEMBER_ME", "my-username", "/auth/realms/master/", 31536000, false, true, "None", false);
assertCookie(response, "KEYCLOAK_SESSION", "my-session", "/auth/realms/master/", 444, false, false, "None", true);
assertCookie(response, "WELCOME_STATE_CHECKER", "my-welcome-csrf", "/auth/realms/master/testing/run-on-server", 300, false, true, "Strict", false);
}