apereo/cas · critical · IllegalArgumentException

JWKS cannot contain expressions

Error message

JWKS cannot contain expressions

What it means

OidcJsonWebKeyStoreJacksonDeserializer rejects any JWKS JSON value containing Spring expression markers (e.g. #{...}) while deserializing the keystore. Because JWKS content may be written to storage and later resolved, embedding Spring EL would allow expression injection; CAS fails fast with this IllegalArgumentException. It is a security guard, not a format problem.

Solutions

  1. Remove any #{...} (or other Spring expression markers) from the JWKS JSON values.
  2. Store literal base64url key material; resolve configuration placeholders before generating the JWKS.
  3. Validate the JWKS file with a scan for '#{' before loading it into CAS.
  4. Treat an occurrence as potential injection and audit where the JWKS came from.

Example fix

// before
{"kty":"RSA","kid":"#{keyId}","n":"..."}
// after
{"kty":"RSA","kid":"my-key-1","n":"..."}
Defensive patterns

Strategy: validation

Validate before calling

if (jwksJson.contains("#{") || jwksJson.contains("${")) {
    throw new IllegalArgumentException("JWKS contains expression markers");
}

Try / catch

try { keystore.load(inputStream); } catch (IllegalArgumentException e) {
    LOGGER.error("Rejected JWKS with expression content: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Loading or storing a JWKS JSON document whose keys' string values (kty, n, e, kid, x5c entries, etc.) contain expression markers like '#{' resolved by SpringExpressionLanguageValueResolver.

Common situations: Administrators pasting template-style values into a JWKS file; YAML/properties templating leaking #{...} placeholders into the keystore; malicious JWKS payloads in multi-tenant setups.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/cc45fb4289cecbba. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-oidc-core-api/src/main/java/org/apereo/cas/oidc/jwks/OidcJsonWebKeyStoreJacksonDeserializer.java:45

        });
    }

    private static void rejectSpringExpressions(final JsonNode node) {
        if (node.isObject()) {
            node.properties().forEach(entry -> {
                rejectSpringExpression(entry.getKey());
                rejectSpringExpressions(entry.getValue());
            });
        } else if (node.isArray()) {
            node.values().forEach(OidcJsonWebKeyStoreJacksonDeserializer::rejectSpringExpressions);
        } else if (node.isString()) {
            rejectSpringExpression(node.asString());
        }
    }

    private static void rejectSpringExpression(final String value) {
        if (SpringExpressionLanguageValueResolver.getInstance().hasExpressionMarkers(value)) {
            throw new IllegalArgumentException("JWKS cannot contain expressions");
        }
    }
}

View on GitHub (pinned to e7288fc434)