diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2DeviceAuthorizationConsentAuthenticationConverter.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2DeviceAuthorizationConsentAuthenticationConverter.java index 54cd5c8fd..17625281b 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2DeviceAuthorizationConsentAuthenticationConverter.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2DeviceAuthorizationConsentAuthenticationConverter.java @@ -80,7 +80,7 @@ public Authentication convert(HttpServletRequest request) { // user_code (REQUIRED) String userCode = parameters.getFirst(OAuth2ParameterNames.USER_CODE); - if (!StringUtils.hasText(userCode) || + if (!OAuth2EndpointUtils.validateUserCode(userCode) || parameters.get(OAuth2ParameterNames.USER_CODE).size() != 1) { OAuth2EndpointUtils.throwError( OAuth2ErrorCodes.INVALID_REQUEST, diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2DeviceVerificationAuthenticationConverter.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2DeviceVerificationAuthenticationConverter.java index 98c090569..ac1ebf553 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2DeviceVerificationAuthenticationConverter.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2DeviceVerificationAuthenticationConverter.java @@ -30,7 +30,6 @@ import org.springframework.security.oauth2.server.authorization.web.OAuth2DeviceVerificationEndpointFilter; import org.springframework.security.web.authentication.AuthenticationConverter; import org.springframework.util.MultiValueMap; -import org.springframework.util.StringUtils; /** * Attempts to extract a user code from {@link HttpServletRequest} for the @@ -49,7 +48,6 @@ public final class OAuth2DeviceVerificationAuthenticationConverter implements Au private static final String ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2"; private static final Authentication ANONYMOUS_AUTHENTICATION = new AnonymousAuthenticationToken( "anonymous", "anonymousUser", AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS")); - @Override public Authentication convert(HttpServletRequest request) { if (!("GET".equals(request.getMethod()) || "POST".equals(request.getMethod()))) { @@ -64,7 +62,7 @@ public Authentication convert(HttpServletRequest request) { // user_code (REQUIRED) String userCode = parameters.getFirst(OAuth2ParameterNames.USER_CODE); - if (!StringUtils.hasText(userCode) || + if (!OAuth2EndpointUtils.validateUserCode(userCode) || parameters.get(OAuth2ParameterNames.USER_CODE).size() != 1) { OAuth2EndpointUtils.throwError( OAuth2ErrorCodes.INVALID_REQUEST, diff --git a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2EndpointUtils.java b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2EndpointUtils.java index 9e2473d32..192489e3d 100644 --- a/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2EndpointUtils.java +++ b/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2EndpointUtils.java @@ -95,4 +95,7 @@ static String normalizeUserCode(String userCode) { return sb.toString(); } + static boolean validateUserCode(String userCode) { + return userCode != null && userCode.toUpperCase().replaceAll("[^A-Z\\d]+", "").length() == 8; + } } diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2DeviceAuthorizationConsentAuthenticationConverterTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2DeviceAuthorizationConsentAuthenticationConverterTests.java index fc87a4442..dfa5ed682 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2DeviceAuthorizationConsentAuthenticationConverterTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2DeviceAuthorizationConsentAuthenticationConverterTests.java @@ -147,6 +147,22 @@ public void convertWhenEmptyUserCodeThenInvalidRequestError() { // @formatter:on } + @Test + public void convertWhenInvalidUserCodeThenInvalidRequestError() { + MockHttpServletRequest request = createRequest(); + request.addParameter(OAuth2ParameterNames.STATE, STATE); + request.addParameter(OAuth2ParameterNames.CLIENT_ID, CLIENT_ID); + request.addParameter(OAuth2ParameterNames.USER_CODE, "LONG-USER-CODE"); + // @formatter:off + assertThatExceptionOfType(OAuth2AuthenticationException.class) + .isThrownBy(() -> this.converter.convert(request)) + .withMessageContaining(OAuth2ParameterNames.USER_CODE) + .extracting(OAuth2AuthenticationException::getError) + .extracting(OAuth2Error::getErrorCode) + .isEqualTo(OAuth2ErrorCodes.INVALID_REQUEST); + // @formatter:on + } + @Test public void convertWhenMultipleUserCodeParametersThenInvalidRequestError() { MockHttpServletRequest request = createRequest(); diff --git a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2DeviceVerificationAuthenticationConverterTests.java b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2DeviceVerificationAuthenticationConverterTests.java index 843d0ee7e..d7d179807 100644 --- a/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2DeviceVerificationAuthenticationConverterTests.java +++ b/oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2DeviceVerificationAuthenticationConverterTests.java @@ -94,6 +94,20 @@ public void convertWhenEmptyUserCodeParameterThenInvalidRequestError() { // @formatter:on } + @Test + public void convertWhenInvalidUserCodeParameterThenInvalidRequestError() { + MockHttpServletRequest request = createRequest(); + request.addParameter(OAuth2ParameterNames.USER_CODE, "LONG-USER-CODE"); + // @formatter:off + assertThatExceptionOfType(OAuth2AuthenticationException.class) + .isThrownBy(() -> this.converter.convert(request)) + .withMessageContaining(OAuth2ParameterNames.USER_CODE) + .extracting(OAuth2AuthenticationException::getError) + .extracting(OAuth2Error::getErrorCode) + .isEqualTo(OAuth2ErrorCodes.INVALID_REQUEST); + // @formatter:on + } + @Test public void convertWhenMultipleUserCodeParameterThenInvalidRequestError() { MockHttpServletRequest request = createRequest();