Medium severity6.1NVD Advisory· Published Mar 20, 2024· Updated Apr 15, 2026
CVE-2024-22258
CVE-2024-22258
Description
Spring Authorization Server versions 1.0.0 - 1.0.5, 1.1.0 - 1.1.5, 1.2.0 - 1.2.2 and older unsupported versions are susceptible to a PKCE Downgrade Attack for Confidential Clients.
Specifically, an application is vulnerable when a Confidential Client uses PKCE for the Authorization Code Grant.
An application is not vulnerable when a Public Client uses PKCE for the Authorization Code Grant.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.springframework.security:spring-security-oauth2-authorization-serverMaven | < 1.1.6 | 1.1.6 |
org.springframework.security:spring-security-oauth2-authorization-serverMaven | >= 1.2.0, < 1.2.3 | 1.2.3 |
Patches
1a7035d22bd2dUpdate PKCE validation
2 files changed · +34 −4
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/CodeVerifierAuthenticator.java+4 −3 modified@@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 the original author or authors. + * Copyright 2020-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -94,8 +94,10 @@ private boolean authenticate(OAuth2ClientAuthenticationToken clientAuthenticatio String codeChallenge = (String) authorizationRequest.getAdditionalParameters() .get(PkceParameterNames.CODE_CHALLENGE); + String codeVerifier = (String) parameters.get(PkceParameterNames.CODE_VERIFIER); if (!StringUtils.hasText(codeChallenge)) { - if (registeredClient.getClientSettings().isRequireProofKey()) { + if (registeredClient.getClientSettings().isRequireProofKey() || + StringUtils.hasText(codeVerifier)) { throwInvalidGrant(PkceParameterNames.CODE_CHALLENGE); } else { if (this.logger.isTraceEnabled()) { @@ -111,7 +113,6 @@ private boolean authenticate(OAuth2ClientAuthenticationToken clientAuthenticatio String codeChallengeMethod = (String) authorizationRequest.getAdditionalParameters() .get(PkceParameterNames.CODE_CHALLENGE_METHOD); - String codeVerifier = (String) parameters.get(PkceParameterNames.CODE_VERIFIER); if (!codeVerifierValid(codeVerifier, codeChallenge, codeChallengeMethod)) { throwInvalidGrant(PkceParameterNames.CODE_VERIFIER); }
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationCodeGrantTests.java+30 −1 modified@@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 the original author or authors. + * Copyright 2020-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -488,6 +488,35 @@ public void requestWhenConfidentialClientWithPkceAndMissingCodeChallengeThenErro assertThat(redirectedUrl).isEqualTo(expectedRedirectUri); } + @Test + public void requestWhenConfidentialClientWithPkceAndMissingCodeChallengeButCodeVerifierProvidedThenBadRequest() throws Exception { + this.spring.register(AuthorizationServerConfiguration.class).autowire(); + + RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); + this.registeredClientRepository.save(registeredClient); + + MultiValueMap<String, String> authorizationRequestParameters = getAuthorizationRequestParameters(registeredClient); + MvcResult mvcResult = this.mvc.perform(get(DEFAULT_AUTHORIZATION_ENDPOINT_URI) + .queryParams(authorizationRequestParameters) + .with(user("user"))) + .andExpect(status().is3xxRedirection()) + .andReturn(); + String redirectedUrl = mvcResult.getResponse().getRedirectedUrl(); + String expectedRedirectUri = authorizationRequestParameters.getFirst(OAuth2ParameterNames.REDIRECT_URI); + assertThat(redirectedUrl).matches(expectedRedirectUri + "\\?code=.{15,}&state=" + STATE_URL_ENCODED); + + String authorizationCode = extractParameterFromRedirectUri(redirectedUrl, "code"); + OAuth2Authorization authorizationCodeAuthorization = this.authorizationService.findByToken(authorizationCode, AUTHORIZATION_CODE_TOKEN_TYPE); + assertThat(authorizationCodeAuthorization).isNotNull(); + assertThat(authorizationCodeAuthorization.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE); + + this.mvc.perform(post(DEFAULT_TOKEN_ENDPOINT_URI) + .params(getTokenRequestParameters(registeredClient, authorizationCodeAuthorization)) + .param(PkceParameterNames.CODE_VERIFIER, S256_CODE_VERIFIER) + .header(HttpHeaders.AUTHORIZATION, getAuthorizationHeader(registeredClient))) + .andExpect(status().isBadRequest()); + } + @Test public void requestWhenCustomTokenGeneratorThenUsed() throws Exception { this.spring.register(AuthorizationServerConfigurationWithTokenGenerator.class).autowire();
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-x637-x8p3-5p22ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-22258ghsaADVISORY
- github.com/spring-projects/spring-authorization-serverghsaPACKAGE
- github.com/spring-projects/spring-authorization-server/commit/a7035d22bd2de6c24e7125623d38fb83d8f659a9ghsaWEB
- spring.io/security/cve-2024-22258nvdWEB
News mentions
0No linked articles in our index yet.