Found while independently verifying an unrelated SSRF report (GHSA-2x48-52jh-cr4g). Neither of these is a security issue — both are correctness bugs that break token issuance / client authentication for legitimately-configured clients.
Bug 1 — missing default for id_token_signed_response_alg causes an NPE at the token endpoint
openam-oauth2/src/main/java/org/forgerock/openam/oauth2/OpenAMClientRegistration.java:508-519 (getIDTokenSignedResponseAlgorithm()) returns null if the attribute was never explicitly persisted, instead of defaulting per the OIDC Core spec (RS256).
openam-oauth2/src/main/java/org/forgerock/openam/oauth2/StatefulTokenStore.java:283 then calls signingAlgorithm.toUpperCase() unguarded → NullPointerException.
- Impact: any client requesting the
openid scope whose idTokenSignedResponseAlg was never explicitly set (e.g. created via a direct realm-config PUT rather than full dynamic registration) gets a 500/server_error from /oauth2/access_token for every grant type, instead of a token.
- Suggested fix: default to
RS256 when unset, and/or null-check before .toUpperCase().
Bug 2 — client-assertion verification dispatches on the wrong client attribute
openam-oauth2/src/main/java/org/forgerock/openam/oauth2/OpenAMClientRegistration.java:654-655 (verifyJwtIdentity()) chooses HMAC vs. asymmetric verification of an incoming private_key_jwt client assertion based on the client's id_token_signed_response_alg — which governs outgoing ID token signing, an unrelated, independently-configurable setting — instead of token_endpoint_auth_method / public_key_selector.
- A client correctly configured for
private_key_jwt + jwks_uri but with id_token_signed_response_alg=HS256 (a common/default ID-token algorithm, chosen independently of how the RP authenticates) gets every asymmetric client assertion routed into verifyJwtBySharedSecret() instead of byJWKs() / byJWKsURI(), failing with JwsSigningException: Unsupported Signing Algorithm, SHA256withRSA — an internal error, not a clean invalid_client.
- Impact: breaks
private_key_jwt authentication for a subset of legitimately-configured clients.
- Suggested fix: dispatch on
getTokenEndpointAuthMethod() / getClientPublicKeySelector() (already used elsewhere in this class) rather than getIDTokenSignedResponseAlgorithm().
Both reproduced against current master (commit 5993d76d5c) via a local Docker instance. Happy to provide full repro steps/logs if helpful.
Found while independently verifying an unrelated SSRF report (GHSA-2x48-52jh-cr4g). Neither of these is a security issue — both are correctness bugs that break token issuance / client authentication for legitimately-configured clients.
Bug 1 — missing default for
id_token_signed_response_algcauses an NPE at the token endpointopenam-oauth2/src/main/java/org/forgerock/openam/oauth2/OpenAMClientRegistration.java:508-519(getIDTokenSignedResponseAlgorithm()) returnsnullif the attribute was never explicitly persisted, instead of defaulting per the OIDC Core spec (RS256).openam-oauth2/src/main/java/org/forgerock/openam/oauth2/StatefulTokenStore.java:283then callssigningAlgorithm.toUpperCase()unguarded →NullPointerException.openidscope whoseidTokenSignedResponseAlgwas never explicitly set (e.g. created via a direct realm-configPUTrather than full dynamic registration) gets a500/server_errorfrom/oauth2/access_tokenfor every grant type, instead of a token.RS256when unset, and/or null-check before.toUpperCase().Bug 2 — client-assertion verification dispatches on the wrong client attribute
openam-oauth2/src/main/java/org/forgerock/openam/oauth2/OpenAMClientRegistration.java:654-655(verifyJwtIdentity()) chooses HMAC vs. asymmetric verification of an incomingprivate_key_jwtclient assertion based on the client'sid_token_signed_response_alg— which governs outgoing ID token signing, an unrelated, independently-configurable setting — instead oftoken_endpoint_auth_method/public_key_selector.private_key_jwt+jwks_uribut withid_token_signed_response_alg=HS256(a common/default ID-token algorithm, chosen independently of how the RP authenticates) gets every asymmetric client assertion routed intoverifyJwtBySharedSecret()instead ofbyJWKs()/byJWKsURI(), failing withJwsSigningException: Unsupported Signing Algorithm, SHA256withRSA— an internal error, not a cleaninvalid_client.private_key_jwtauthentication for a subset of legitimately-configured clients.getTokenEndpointAuthMethod()/getClientPublicKeySelector()(already used elsewhere in this class) rather thangetIDTokenSignedResponseAlgorithm().Both reproduced against current
master(commit5993d76d5c) via a local Docker instance. Happy to provide full repro steps/logs if helpful.