[java-idp-oidc] 03/03: JOIDC-301 - Unnecessary PKCE verifier in the token request is silently ignored

Codeberg noreply at shibboleth.net
Thu Nov 5 17:34:39 UTC 2026


This is an automated email from the git hooks/post-receive script.

codeberg pushed a commit to branch main
in repository java-idp-oidc.

View the commit online:
https://codeberg.org/Shibboleth/java-idp-oidc/commit/be57e339c2d5ac60219c3f6d673732f2caa3bc67

commit be57e339c2d5ac60219c3f6d673732f2caa3bc67
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Thu Nov 5 19:33:29 2026 +0200

    JOIDC-301 - Unnecessary PKCE verifier in the token request is silently ignored
    
    https://shibboleth.atlassian.net/browse/JOIDC-301
    
    Compare to the authorization request contents and raise an error if they don't match. Cover in flow tests.
---
 .../plugin/oidc/op/profile/impl/ValidatePKCE.java   | 16 ++++++++++++----
 .../plugin/oidc/op/profile/flow/TokenFlowTest.java  | 21 +++++++++++++++++++++
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidatePKCE.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidatePKCE.java
index 241b7d8c..c0b99503 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidatePKCE.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidatePKCE.java
@@ -140,12 +140,20 @@ public class ValidatePKCE extends AbstractOIDCResponseAction {
         plainPKCE = allowPKCEPlainCondition.test(profileRequestContext);
         
         codeChallenge = tokenClaimsSet.getCodeChallenge();
+        codeVerifier = codeVerifierLookupStrategy.apply(profileRequestContext);
         // Checks whether PKCE needs to be validated.
-        if (StringSupport.trimOrNull(codeChallenge) == null && !forcePKCE) {
-            log.debug("{} No PKCE code challenge in request, nothing to do", getLogPrefix());
-            return false;
+        if (StringSupport.trimOrNull(codeChallenge) == null) {
+            if (codeVerifier != null) {
+                log.warn("{} The token request contains the PKCE code verifier, but no challenge presented " +
+                        "in authorization request", getLogPrefix());
+                ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_MESSAGE);
+                return false;
+            }
+            if (!forcePKCE) {
+                log.debug("{} No PKCE code challenge in request, nothing to do", getLogPrefix());
+                return false;
+            }
         }
-        codeVerifier = codeVerifierLookupStrategy.apply(profileRequestContext);
         return true;
     }
 
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/TokenFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/TokenFlowTest.java
index 5e3291ae..2ce036e3 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/TokenFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/TokenFlowTest.java
@@ -1667,6 +1667,27 @@ public class TokenFlowTest extends AbstractOidcClientAuthenticationFlowTest {
         Assert.assertNotNull(response.getTokens().getAccessToken());
     }
 
+    @Test
+    public void testValidGrantPlainPKCESolelyInTokenRequest() throws Exception {
+        initializeGrantAndRequest(clientIdPkcePlainUnforced,
+                createRequestParameters(redirectUri, "authorization_code",
+                buildAuthorizationCode(clientIdPkcePlainUnforced), clientIdPkcePlainUnforced, null, null, 
+                codeVerifier));
+        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+        assertErrorCode(result, OAuth2Error.INVALID_REQUEST_CODE);
+        assertErrorDescriptionContains(result, "InvalidMessage");
+    }
+
+    @Test
+    public void testValidGrantPlainPKCENoChallengeNoVerifier() throws Exception {
+        initializeGrantAndRequest(clientIdPkcePlain,
+                createRequestParameters(redirectUri, "authorization_code",
+                buildAuthorizationCode(clientIdPkcePlain), clientIdPkcePlain, null, null, null));
+        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+        assertErrorCode(result, OAuth2Error.INVALID_REQUEST_CODE);
+        assertErrorDescriptionContains(result, "InvalidMessage");
+    }
+
     @Test
     public void testValidGrantValidPlainPKCE_publicClient() throws Exception {
         initializeGrantAndRequest(clientIdPkcePlainPublic, createRequestParameters(redirectUri, "authorization_code",

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list