-
Bug
-
Resolution: Done
-
Undefined
-
None
-
False
-
-
False
-
-
Before reporting an issue
[x] I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.
Area
oidc
Describe the bug
The optional login_hint parameter in the OIDC login URL is accepted without any size validation. When supplied with a long value, it is:
- Reflected into the email/username field on the login form
- Stored in the authentication session
- Serialized into the KC_RESTART cookie
If the resulting cookie exceeds the ~4096-byte browser limit, it is dropped or truncated by the browser. This breaks the login flow, resulting in:
- Blank 0-byte responses
- Intermittent redirect loops
- In some cases, HTTP 502 errors
This leads to unstable authentication behavior and increased backend load. The issue reflects uncontrolled input handling in a core login path, affecting reliability and availability.
Version
Observed in multiple real-world deployments Keycloak v17+. Issue is present in latest source code as of June 2025.
Regression
[ ] The issue is a regression
Expected behavior
The optional login_hint parameter should have a reasonable length limit and be validated before:
- Being reflected into the login form (e.g., email/username field).
- Being stored in the authentication session via.
- Being serialized into the KC_RESTART cookie.
This would prevent cookie overflow, preserve session integrity, and ensure stable login behavior.
Actual behavior
The optional login_hint parameter is accepted and processed without size validation. When a long value is supplied:
- It is reflected directly into the login form's email field.
- It is stored in session notes and serialized into the KC_RESTART cookie.
- The resulting KC_RESTART cookie can exceed the ~4096-byte browser limit.
When the cookie becomes oversized:
- The browser silently drops or truncates it.
- Keycloak cannot resume the session.
- This results in broken login behavior such as:
- Blank 0-byte HTTP responses
- Occasional redirect loops
- HTTP 502 errors in some environments
!Image
Screenshot from a real-world deployment demonstrating the KC_RESTART cookie exceeding 4096 bytes(environment details redacted)
How to Reproduce?
1. Set up a default Keycloak instance (17+), using standard OIDC login flow.
2. Create a login URL with a very long login_hint value, such as:
https://<keycloak-domain>/realms/<realm-name>/protocol/openid-connect/auth?login_hint=AAAA...AAAA (e.g., 4000+ characters)&client_id=your-client-id&response_type=code&scope=openid&redirect_uri=https://your-app.com/callback
3. Visit the URL in a [browser.]
4. Observe:
- The long login_hint appears in the email/username field on the login page.
- In browser console and dev tools, the KC_RESTART cookie is large or near the 4096-byte limit.
Anything else?
Technical References (login_hint Flow)
All of the following paths and snippets are taken directly from Keycloak’s source code (main). They show how the optional login_hint parameter propagates without size checks.
Parameter Definition
File: OIDCLoginProtocol.java
Path: services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
Link: https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
public static final String LOGIN_HINT_PARAM = "login_hint";
> No length or format checks when reading this optional parameter.
Reflected in the Login Form
File: FreeMarkerLoginFormsProvider.java
Path: services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProvider.java
Link: https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/forms/login/freemarker/FreeMarkerLoginFormsProvider.java
login.username = escape(kcContext.getLoginHint());
> No validation or size limit before reflecting user input into the UI (even though escaped).
Stored in Session Notes
File: AuthorizationEndpoint.java
Path: services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
Link: https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
authSession.setClientNote(OIDCLoginProtocol.LOGIN_HINT_PARAM, loginHint);
> setClientNote(...) accepts any length; no bounds or format checks before adding to session.
Session Note Interface
File: AuthenticationSessionModel.java (JavaDoc)
Link: https://www.keycloak.org/docs-api/latest/javadocs/org/keycloak/sessions/AuthenticationSessionModel.html
void setClientNote(String name, String value); String getClientNote(String name);
> No maximum length or sanitization of client notes—allows unbounded session data.
Serialized into the KC_RESTART Cookie
File: RestartLoginCookie.java
Path: services/src/main/java/org/keycloak/protocol/oidc/utils/RestartLoginCookie.java
Link: https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/protocol/oidc/utils/RestartLoginCookie.java
for (Map.Entry<String, String> entry : authSession.getClientNotes().entrySet()) {
notes.put(entry.getKey(), entry.getValue());
}
String encoded = encodeAndEncrypt(session, restart);
session.getProvider(CookieProvider.class).set(CookieType.AUTH_RESTART, encoded);
> No check on total cookie size (e.g., the 4096‑byte browser limit) before setting it.
Summary of Missing Validations
- No input length limits on login_hint anywhere.
- No format or sanitization checks before reflecting, storing, or serializing the value.
- No aggregate cookie size enforcement, leading to session corruption and broken login flows.
This behavior has been observed across three real-world Keycloak deployments during responsible bug bounty testing. The issue has been confirmed directly from Keycloak's source code, and it affects both the latest and previous versions using the default OIDC login flow.
- links to