This is an automated email from the ASF dual-hosted git repository. rzo1 pushed a commit to branch tomee-10.x in repository https://gitbox.apache.org/repos/asf/tomee.git
commit b12d24c6ce54d7ea2b7c0ea029a84c8a1225295c Author: Richard Zowalla <[email protected]> AuthorDate: Mon Sep 7 19:45:50 2026 +0200 use secure random for OIDC nonce/state Backport of cf27717d523d700d4f8f8a4ec3f86a401bb54c42 from main, adapted: main's test additions target CookieBasedOpenIdStorageHandlerTest, which does not exist on this branch, so the token properties are covered by a new OpenIdStorageHandlerTokenTest instead. OpenIdStorageHandler built the OIDC state and nonce with RandomStringUtils.random(10, true, true), which draws from a non-cryptographic java.util.Random and yields only 10 alphanumeric characters. Use a SecureRandom-backed 256-bit URL-safe token instead, and compare the returned state against the stored one with MessageDigest.isEqual so the check is not short-circuiting. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01N6nczXevSpJfF5Ly8ju2W9 --- .../cdi/OpenIdAuthenticationMechanism.java | 5 ++- .../cdi/openid/storage/OpenIdStorageHandler.java | 15 ++++++--- .../storage/OpenIdStorageHandlerTokenTest.java | 39 ++++++++++++++++++++++ 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/OpenIdAuthenticationMechanism.java b/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/OpenIdAuthenticationMechanism.java index 28cadfb56d..f61759fe5d 100644 --- a/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/OpenIdAuthenticationMechanism.java +++ b/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/OpenIdAuthenticationMechanism.java @@ -50,6 +50,8 @@ import javax.security.auth.callback.Callback; import javax.security.auth.callback.UnsupportedCallbackException; import java.io.IOException; import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; import java.util.Arrays; import java.util.stream.Collectors; @@ -234,7 +236,8 @@ public class OpenIdAuthenticationMechanism implements HttpAuthenticationMechanis return messageContext.notifyContainerAboutLogin(CredentialValidationResult.NOT_VALIDATED_RESULT); } - if (!state.equals(storageHandler.getStoredState(request, response))) { + if (!MessageDigest.isEqual(state.getBytes(StandardCharsets.UTF_8), + storageHandler.getStoredState(request, response).getBytes(StandardCharsets.UTF_8))) { return messageContext.notifyContainerAboutLogin(CredentialValidationResult.INVALID_RESULT); } diff --git a/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/openid/storage/OpenIdStorageHandler.java b/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/openid/storage/OpenIdStorageHandler.java index cf12ee43d1..7139047a40 100644 --- a/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/openid/storage/OpenIdStorageHandler.java +++ b/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/openid/storage/OpenIdStorageHandler.java @@ -16,13 +16,14 @@ */ package org.apache.tomee.security.cdi.openid.storage; -import org.apache.commons.lang3.RandomStringUtils; - import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import java.security.SecureRandom; +import java.util.Base64; public abstract class OpenIdStorageHandler { protected static final String PREFIX = "openid."; + private static final SecureRandom RANDOM = new SecureRandom(); public static final String REQUEST_KEY = "REQUEST"; public static final String STATE_KEY = "STATE"; @@ -39,7 +40,7 @@ public abstract class OpenIdStorageHandler { } public String createNewState(HttpServletRequest request, HttpServletResponse response) { - String state = RandomStringUtils.random(10, true, true); + String state = newToken(); set(request, response, STATE_KEY, state); return state; @@ -50,9 +51,15 @@ public abstract class OpenIdStorageHandler { } public String createNewNonce(HttpServletRequest request, HttpServletResponse response) { - String nonce = RandomStringUtils.random(10, true, true); + String nonce = newToken(); set(request, response, NONCE_KEY, nonce); return nonce; } + + static String newToken() { + final byte[] bytes = new byte[32]; + RANDOM.nextBytes(bytes); + return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes); + } } diff --git a/tomee/tomee-security/src/test/java/org/apache/tomee/security/cdi/openid/storage/OpenIdStorageHandlerTokenTest.java b/tomee/tomee-security/src/test/java/org/apache/tomee/security/cdi/openid/storage/OpenIdStorageHandlerTokenTest.java new file mode 100644 index 0000000000..7e92bec891 --- /dev/null +++ b/tomee/tomee-security/src/test/java/org/apache/tomee/security/cdi/openid/storage/OpenIdStorageHandlerTokenTest.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tomee.security.cdi.openid.storage; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class OpenIdStorageHandlerTokenTest { + + @Test + public void newTokenProducesLongUniqueUrlSafeTokens() { + final Set<String> seen = new HashSet<>(); + for (int i = 0; i < 1000; i++) { + final String token = OpenIdStorageHandler.newToken(); + assertEquals(43, token.length()); + assertTrue(token.matches("[A-Za-z0-9_-]+")); + assertTrue(seen.add(token)); + } + } +}
