Tony Panza created SOLR-18073:
---------------------------------

             Summary: JWTAuthPlugin claimsMatch fails with 
MalformedClaimException for non-string claims (e.g., booleans)
                 Key: SOLR-18073
                 URL: https://issues.apache.org/jira/browse/SOLR-18073
             Project: Solr
          Issue Type: Bug
          Components: Authentication, security
    Affects Versions: 9.10, 9.9, 9.8, 9.7
            Reporter: Tony Panza


The claimsMatch configuration option in JWTAuthPlugin only works with 
string-valued JWT claims. When a claim configured in claimsMatch has a 
non-string value (e.g., a JSON boolean like email_verified: true), 
authentication fails with HTTP 400 "Invalid JWT" instead of matching the claim 
value.

  Root Cause:

  In JWTAuthPlugin.authenticate() (lines 575-594), the code calls 
jwtClaims.getStringClaimValue(claim) to retrieve claim values for regex 
matching:

  if 
(!entry.getValue().matcher(jwtClaims.getStringClaimValue(claim)).matches()) {

  When the claim is not a string (e.g., a boolean), Jose4j throws 
MalformedClaimException. This exception is caught at line 706-708 and returns 
JWT_PARSE_ERROR:

  } catch (MalformedClaimException e) {
    return new JWTAuthenticationResponse(
        AuthCode.JWT_PARSE_ERROR, "Malformed claim, error was: " + 
e.getMessage());

  Impact:

  Users cannot use claimsMatch to validate common OIDC claims that are 
booleans, such as:
  - email_verified (boolean in OIDC spec)
  - Custom boolean claims from identity providers

  Steps to Reproduce:

  1. Configure JWTAuthPlugin with:
  {
    "claimsMatch": {
      "email_verified": "true"
    }
  }

  2. Send a request with a valid JWT containing "email_verified": true 
(boolean, not string)
  3. Observe HTTP 400 with message "Invalid JWT" / "Malformed claim"

  Expected Behavior:

  The plugin should convert non-string claim values to strings before regex 
matching, allowing claimsMatch to work with boolean, numeric, and other JSON 
types.

  Suggested Fix:

  Replace getStringClaimValue(claim) with getClaimValue(claim) and convert the 
result to a string:
  Object claimValue = jwtClaims.getClaimValue(claim);
  String claimValueStr = claimValue != null ? claimValue.toString() : null;
  if (claimValueStr == null || 
!entry.getValue().matcher(claimValueStr).matches()) {

  Test Case:

  A unit test demonstrating this bug has been written in 
JWTAuthPluginTest.testClaimMatchWithBooleanClaim().

[https://github.com/tpanza/solr/commit/feaee4dcc5ec392c88692bf37c206345fba6b2a1]
 



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to