This is an automated email from the ASF dual-hosted git repository.

coheigea pushed a commit to branch 4.1.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git

commit 544a714507c375b3d15de40b67ce957c4ddff158
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Fri Sep 25 14:41:45 2026 +0100

    Tighten scope and application_type validation in DynamicRegistrationService 
(#3506)
    
    (cherry picked from commit 2d8c3c8abeafb14294d765beb0643fc91e55fcc7)
---
 .../services/DynamicRegistrationService.java       | 13 ++++++++-
 .../services/DynamicRegistrationServiceTest.java   | 33 ++++++++++++++++++++++
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git 
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationService.java
 
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationService.java
index ecb4847e8ad..5bf67cae103 100644
--- 
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationService.java
+++ 
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationService.java
@@ -20,6 +20,7 @@ package org.apache.cxf.rs.security.oauth2.services;
 
 import java.net.URI;
 import java.security.cert.X509Certificate;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -270,6 +271,9 @@ public class DynamicRegistrationService {
         String appType = request.getApplicationType();
         if (appType == null) {
             appType = DEFAULT_APPLICATION_TYPE;
+        } else if (!WEB_APPLICATION_TYPE.equalsIgnoreCase(appType)
+            && !NATIVE_APPLICATION_TYPE.equalsIgnoreCase(appType)) {
+            reportInvalidRequestError(new OAuthError(INVALID_CLIENT_METADATA, 
"Unsupported application type"));
         }
         boolean isConfidential = DEFAULT_APPLICATION_TYPE.equals(appType)
             && (passwordRequired
@@ -394,6 +398,10 @@ public class DynamicRegistrationService {
             List<String> requestedScopes = OAuthUtils.parseScope(scope);
             validateClientScopes(requestedScopes);
             client.setRegisteredScopes(requestedScopes);
+        } else if (allowedClientScopes != null && 
client.getRegisteredScopes().isEmpty()) {
+            // An empty list of registered scopes allows any scope to be 
requested later on,
+            // so restrict the client to the configured scopes instead
+            client.setRegisteredScopes(new ArrayList<>(allowedClientScopes));
         }
         // Client Application URI
         String clientUri = request.getClientUri();
@@ -466,6 +474,9 @@ public class DynamicRegistrationService {
                 reportInvalidRequestError(new 
OAuthError(INVALID_CLIENT_METADATA,
                     "Unsupported redirect URI hostname for scheme"));
             }
+        } else {
+            reportInvalidRequestError(new OAuthError(INVALID_CLIENT_METADATA,
+                "Unsupported application type"));
         }
     }
 
@@ -533,7 +544,7 @@ public class DynamicRegistrationService {
 
         List<String> allowedScopes = allowedClientScopes;
         if (allowedScopes == null && clientProvider instanceof 
AbstractOAuthDataProvider) {
-            allowedScopes = new java.util.ArrayList<>(
+            allowedScopes = new ArrayList<>(
                 
((AbstractOAuthDataProvider)clientProvider).getPermissionMap().keySet());
         }
 
diff --git 
a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationServiceTest.java
 
b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationServiceTest.java
index 3bfaceafffa..1b5593ad74f 100644
--- 
a/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationServiceTest.java
+++ 
b/rt/rs/security/oauth-parent/oauth2/src/test/java/org/apache/cxf/rs/security/oauth2/services/DynamicRegistrationServiceTest.java
@@ -90,6 +90,39 @@ public class DynamicRegistrationServiceTest {
         assertEquals(Collections.singletonList("openid"), 
client.getRegisteredScopes());
     }
 
+    @Test
+    public void testDefaultsToAllowedScopesWhenNoScopeRegistered() {
+        TestDynamicRegistrationService service = new 
TestDynamicRegistrationService();
+        service.setAllowedClientScopes(Collections.singletonList("read"));
+
+        Client client = createClient();
+        service.applyClientRegistration(new ClientRegistration(), client);
+
+        assertEquals(Collections.singletonList("read"), 
client.getRegisteredScopes());
+    }
+
+    @Test
+    public void testRejectsUnknownApplicationTypeRedirectUrl() {
+        TestDynamicRegistrationService service = new 
TestDynamicRegistrationService();
+
+        ClientRegistration request = new ClientRegistration();
+        request.setApplicationType("x");
+        request.setRedirectUris(List.of("http://evil.example/cb";));
+
+        Client client = createClient();
+        
client.setAllowedGrantTypes(Collections.singletonList(OAuthConstants.IMPLICIT_GRANT));
+        assertThrows(BadRequestException.class, () -> 
service.applyClientRegistration(request, client));
+    }
+
+    @Test
+    public void testRejectsUnknownApplicationType() {
+        TestDynamicRegistrationService service = new 
TestDynamicRegistrationService();
+
+        ClientRegistration request = new ClientRegistration();
+        request.setApplicationType("x");
+        assertThrows(BadRequestException.class, () -> 
service.createClient(request));
+    }
+
     @Test
     public void testAcceptsAllowedRedirectUrlsWebApp() {
         TestDynamicRegistrationService service = new 
TestDynamicRegistrationService();

Reply via email to