false all additional request parameters
+ * that to not meet the configuration are silently ignored. If true an exception will be raised.
+ */
+ private final boolean additionalReqParamsFailFast;
+
+ /**
+ * Default value for {@link #additionalReqParamsMaxOverallSize} in case no configuration property is set.
+ */
+ public static final int DEFAULT_ADDITIONAL_REQ_PARAMS_MAX_OVERALL_SIZE = Integer.MAX_VALUE;
+
+ /**
+ * Max size of all additional request parameters value copied into client session note to prevent DoS attacks.
+ */
+ private final int additionalReqParamsMaxOverallSize;
+
+
+ public OIDCProviderConfig(Config.Scope config) {
+ this.additionalReqParamsMaxNumber = config.getInt(OIDCLoginProtocolFactory.CONFIG_OIDC_REQ_PARAMS_MAX_NUMBER, DEFAULT_ADDITIONAL_REQ_PARAMS_MAX_NUMBER);
+ this.additionalReqParamsMaxSize = config.getInt(OIDCLoginProtocolFactory.CONFIG_OIDC_REQ_PARAMS_MAX_SIZE, DEFAULT_ADDITIONAL_REQ_PARAMS_MAX_SIZE);
+ this.additionalReqParamsMaxOverallSize = config.getInt(OIDCLoginProtocolFactory.CONFIG_OIDC_REQ_PARAMS_MAX_OVERALL_SIZE, DEFAULT_ADDITIONAL_REQ_PARAMS_MAX_OVERALL_SIZE);
+ this.additionalReqParamsFailFast = config.getBoolean(OIDCLoginProtocolFactory.CONFIG_OIDC_REQ_PARAMS_FAIL_FAST, DEFAULT_ADDITIONAL_REQ_PARAMS_FAIL_FAST);
+ }
+
+ public int getAdditionalReqParamsMaxNumber() {
+ return additionalReqParamsMaxNumber;
+ }
+
+ public int getAdditionalReqParamsMaxSize() {
+ return additionalReqParamsMaxSize;
+ }
+
+ public boolean isAdditionalReqParamsFailFast() {
+ return additionalReqParamsFailFast;
+ }
+
+ public int getAdditionalReqParamsMaxOverallSize() {
+ return additionalReqParamsMaxOverallSize;
+ }
+}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/request/AuthorizationEndpointRequestParserProcessor.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/request/AuthorizationEndpointRequestParserProcessor.java
index 58ff5a6a68a..e3248493949 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/request/AuthorizationEndpointRequestParserProcessor.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/request/AuthorizationEndpointRequestParserProcessor.java
@@ -53,7 +53,7 @@ public class AuthorizationEndpointRequestParserProcessor {
try {
AuthorizationEndpointRequest request = new AuthorizationEndpointRequest();
boolean isResponseTypeParameterRequired = isResponseTypeParameterRequired(requestParams, endpointType);
- AuthzEndpointQueryStringParser parser = new AuthzEndpointQueryStringParser(requestParams, isResponseTypeParameterRequired);
+ AuthzEndpointQueryStringParser parser = new AuthzEndpointQueryStringParser(session, requestParams, isResponseTypeParameterRequired);
parser.parseRequest(request);
if (parser.getInvalidRequestMessage() != null) {
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/request/AuthzEndpointQueryStringParser.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/request/AuthzEndpointQueryStringParser.java
index 3cb65424fad..120f7c6e22d 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/request/AuthzEndpointQueryStringParser.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/request/AuthzEndpointQueryStringParser.java
@@ -22,6 +22,7 @@ import jakarta.ws.rs.core.MultivaluedMap;
import java.util.Set;
import org.jboss.logging.Logger;
+import org.keycloak.models.KeycloakSession;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
/**
@@ -39,7 +40,8 @@ public class AuthzEndpointQueryStringParser extends AuthzEndpointRequestParser {
private String invalidRequestMessage = null;
- public AuthzEndpointQueryStringParser(MultivaluedMap+ * You can toggle the behavior by setting ({@code additionalReqParamsFailFast}) that enables the fail-fast principle. + * Any request parameter in violation of the configuration results in an + * error response, e.g., + *
+ * Additionally, ({@code additionalReqParamMaxOverallSize}) can be configured
+ * that sets the maximum of size of all parameters combined. If not provided, {@link Integer#MAX_VALUE} will be used.
+ *
+ * @author Manuel Schallar
* @author Marek Posolda
*/
public abstract class AuthzEndpointRequestParser {
private static final Logger logger = Logger.getLogger(AuthzEndpointRequestParser.class);
- /**
- * Max number of additional req params copied into client session note to prevent DoS attacks
- *
- */
- public static final int ADDITIONAL_REQ_PARAMS_MAX_MUMBER = 5;
-
- /**
- * Max size of additional req param value copied into client session note to prevent DoS attacks - params with longer value are ignored
- *
- */
- public static final int ADDITIONAL_REQ_PARAMS_MAX_SIZE = 2000;
+ protected final int additionalReqParamsMaxNumber;
+ protected final int additionalReqParamsMaxSize;
+ protected final boolean additionalReqParamsFailFast;
+ protected final int additionalReqParamsMaxOverallSize;
public static final String AUTHZ_REQUEST_OBJECT = "ParsedRequestObject";
public static final String AUTHZ_REQUEST_OBJECT_ENCRYPTED = "EncryptedRequestObject";
@@ -83,6 +102,15 @@ public abstract class AuthzEndpointRequestParser {
KNOWN_REQ_PARAMS.add(OAuth2Constants.CLIENT_SECRET);
}
+ protected AuthzEndpointRequestParser(KeycloakSession keycloakSession) {
+ OIDCLoginProtocol loginProtocol = (OIDCLoginProtocol) keycloakSession.getProvider(LoginProtocol.class, OIDCLoginProtocol.LOGIN_PROTOCOL);
+ OIDCProviderConfig config = loginProtocol.getConfig();
+ this.additionalReqParamsMaxNumber = config.getAdditionalReqParamsMaxNumber();
+ this.additionalReqParamsMaxSize = config.getAdditionalReqParamsMaxSize();
+ this.additionalReqParamsFailFast = config.isAdditionalReqParamsFailFast();
+ this.additionalReqParamsMaxOverallSize = config.getAdditionalReqParamsMaxOverallSize();
+ }
+
public void parseRequest(AuthorizationEndpointRequest request) {
String clientId = getParameter(OIDCLoginProtocol.CLIENT_ID_PARAM);
if (clientId != null && request.clientId != null && !request.clientId.equals(clientId)) {
@@ -130,23 +158,61 @@ public abstract class AuthzEndpointRequestParser {
}
protected void extractAdditionalReqParams(Map