[java-oidfed-common] 01/02: Handle unrecognized members of naming_constraints as a failure

Codeberg noreply at shibboleth.net
Thu Oct 8 15:22:48 UTC 2026


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

codeberg pushed a commit to branch main
in repository java-oidfed-common.

View the commit online:
https://codeberg.org/Shibboleth/java-oidfed-common/commit/db3b184c9f95cbfca3aff385a7f215889761466e

commit db3b184c9f95cbfca3aff385a7f215889761466e
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Thu Oct 8 16:01:59 2026 +0300

    Handle unrecognized members of naming_constraints as a failure
    
    - Cover in tests
---
 .../cache/SubordinateStatementMetadataCacheTest.java  | 19 +++++++++++++++++++
 .../impl/DefaultNamingConstraintsConstraint.java      | 10 ++++++----
 .../claims/impl/ConstraintsSyntaxClaimsValidator.java |  4 ++++
 .../impl/DefaultNamingConstraintsConstraintTest.java  |  9 +++++++++
 4 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/SubordinateStatementMetadataCacheTest.java b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/SubordinateStatementMetadataCacheTest.java
index 9ab38a9..594603c 100644
--- a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/SubordinateStatementMetadataCacheTest.java
+++ b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/cache/SubordinateStatementMetadataCacheTest.java
@@ -500,6 +500,25 @@ public class SubordinateStatementMetadataCacheTest extends AbstractFederationFlo
         assertNoSubordinateStatement(entityId);
     }
 
+    @Test
+    public void testInvalidConstraints_namingConstraint_unrecognizedMember()
+            throws MetadataCacheException, UnsupportedOperationException, IOException, URISyntaxException {
+        final String entityId = uniqueClientId();
+        final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder().issuer(anchorId).subject(entityId)
+                .issueTime(Date.from(Instant.now()))
+                .expirationTime(Date.from(Instant.now().plusSeconds(300)))
+                .claim("jwks", new JWKSet(leafKey).toJSONObject(true))
+                .claim("constraints", Map.of("naming_constraints", Map.of("unrecognized", List.of("value"))))
+                .claim("metadata", Map.of("federation_entity", Collections.emptyMap()));
+        final String subordinateStatement = FederationJwtSupport.signedJwt(
+                JWSAlgorithm.RS256, trustedAnchorKey, "entity-statement+jwt", builder.build()).serialize();
+
+        mapResponse(entityConfigurationUrl(anchorId), mockResponse(trustedAnchorConfiguration()));
+        mapResponse(subordinateStatementUrl(anchorFetchEndpoint, entityId),
+                mockResponse(subordinateStatement));
+        assertNoSubordinateStatement(entityId);
+    }
+
     @Test
     public void testInvalidConstraints_allowedEntityTypes()
             throws MetadataCacheException, UnsupportedOperationException, IOException, URISyntaxException {
diff --git a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/constraints/impl/DefaultNamingConstraintsConstraint.java b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/constraints/impl/DefaultNamingConstraintsConstraint.java
index 210d207..4c02037 100644
--- a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/constraints/impl/DefaultNamingConstraintsConstraint.java
+++ b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/constraints/impl/DefaultNamingConstraintsConstraint.java
@@ -50,7 +50,6 @@ public class DefaultNamingConstraintsConstraint extends AbstractFederationPolicy
             throws ConstraintViolationException {
         if (constraint instanceof Map<?,?> map) {
             final Map<String, List<String>> result = map.keySet().stream()
-                    .filter(key -> "permitted".equals(key) || "excluded".equals(key))
                     .map(String::valueOf)
                     .collect(Collectors.toMap(key -> key, key -> parseListOfStrings(key, map.get(key))));
             assert result != null;
@@ -61,15 +60,18 @@ public class DefaultNamingConstraintsConstraint extends AbstractFederationPolicy
     }
 
     /**
-     * Parses the raw object value into a list of strings.
+     * Verifies the key and parses the raw object value into a list of strings.
      * 
-     * @param key the key (used solely in a potential exception)
+     * @param key the key to be verified that it's a recognized member of the constraint 
      * @param raw the value to be parsed
      * @return the value as list of strings
-     * @throws ConstraintViolationException if a non-null value could not be parsed or if a value was null
+     * @throws ConstraintViolationException if key fails the validation or value cannot be parsed
      */
     @Nonnull private List<String> parseListOfStrings(@Nullable final String key, @Nullable final Object raw)
             throws ConstraintViolationException {
+        if (!("excluded".equals(key) || "permitted".equals(key))) {
+            throw new ConstraintViolationException("The key " + key + " is not a recognized member of this constraint");
+        }
         if (raw instanceof List<?> list) {
             final List<String> result = list.stream().filter(String.class::isInstance).map(String::valueOf).toList();
             if (result.size() == list.size()) {
diff --git a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/security/jwt/claims/impl/ConstraintsSyntaxClaimsValidator.java b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/security/jwt/claims/impl/ConstraintsSyntaxClaimsValidator.java
index f24fe88..386d015 100644
--- a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/security/jwt/claims/impl/ConstraintsSyntaxClaimsValidator.java
+++ b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/security/jwt/claims/impl/ConstraintsSyntaxClaimsValidator.java
@@ -83,6 +83,10 @@ public class ConstraintsSyntaxClaimsValidator extends AbstractClaimsValidator {
                 if (!(key instanceof String)) {
                     throw new JWTValidationException(errorPrefix + "key is not a string");
                 }
+                if (!("permitted".equals(key) || "excluded".equals(key))) {
+                    throw new JWTValidationException(
+                            errorPrefix + "key " + key + " is not a recognized member of this constraint");
+                }
                 if (map.get(key) instanceof List<?> list) {
                     for (final Object item : list) {
                         if (!(item instanceof String)) {
diff --git a/oidfed-common-impl/src/test/java/net/shibboleth/oidfed/metadata/constraints/impl/DefaultNamingConstraintsConstraintTest.java b/oidfed-common-impl/src/test/java/net/shibboleth/oidfed/metadata/constraints/impl/DefaultNamingConstraintsConstraintTest.java
index 4632b63..dcbc282 100644
--- a/oidfed-common-impl/src/test/java/net/shibboleth/oidfed/metadata/constraints/impl/DefaultNamingConstraintsConstraintTest.java
+++ b/oidfed-common-impl/src/test/java/net/shibboleth/oidfed/metadata/constraints/impl/DefaultNamingConstraintsConstraintTest.java
@@ -58,6 +58,15 @@ public class DefaultNamingConstraintsConstraintTest extends AbstractConstraintTe
         Assert.assertFalse(constraint.validate(constraints, subordinate, initTrustChain(entity, subordinate)));
     }
 
+    @Test
+    public void validate_wrongInput_unrecognizedKey_shouldReturnFalse() {
+        final var constraints = new HashMap<String, List<String>>();
+        constraints.put("unrecognized", List.of("value1"));
+        final EntityConfiguration entity = initEntityConfiguration("https://entity.federation.local");
+        final SubordinateStatement subordinate = mock(SubordinateStatement.class);
+        Assert.assertFalse(constraint.validate(constraints, subordinate, initTrustChain(entity, subordinate)));
+    }
+
     @Test
     public void validate_wrongInput_nullPermitted_shouldReturnFalse() {
         final var constraints = new HashMap<String, List<String>>();

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


More information about the commits mailing list