logo

CVE-2023-36820 io.micronaut.security:micronaut-security-oauth2

Package

Manager: maven
Name: io.micronaut.security:micronaut-security-oauth2
Vulnerable Version: >=3.11.0 <3.11.1 || >=3.10.0 <3.10.2 || >=3.9.0 <3.9.6 || >=3.8.0 <3.8.4 || >=3.7.0 <3.7.4 || >=3.6.0 <3.6.6 || >=3.5.0 <3.5.3 || >=3.4.0 <3.4.3 || >=3.3.0 <3.3.2 || >=3.2.0 <3.2.4 || >=3.1.0 <3.1.2

Severity

Level: Medium

CVSS v3.1: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N

CVSS v4.0: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N

EPSS: 0.00283 pctl0.51312

Details

io.micronaut.security:micronaut-security-oauth2 has invalid IdTokenClaimsValidator logic on aud ### Summary IdTokenClaimsValidator skips `aud` claim validation if token is issued by same identity issuer/provider. ### Details See https://github.com/micronaut-projects/micronaut-security/blob/master/security-oauth2/src/main/java/io/micronaut/security/oauth2/client/IdTokenClaimsValidator.java#L202 This logic violates point 3 of https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation. Workaround exists by setting `micronaut.security.token.jwt.claims-validators.audience` with valid values. `micronaut.security.token.jwt.claims-validators.openid-idtoken` can be kept as default on. ### PoC Should probably be: ```java return issuer.equalsIgnoreCase(iss) && audiences.contains(clientId) && validateAzp(claims, clientId, audiences); ``` ### Impact Any OIDC setup using Micronaut where multiple OIDC applications exists for the same issuer but token auth are not meant to be shared. ### Mitigation Please upgrade to a patched `micronaut-security-oauth2` release as soon as possible. If you cannot upgrade, for example, if you are still using Micronaut Framework 2, you can patch your application by creating a replacement of `IdTokenClaimsValidatorReplacement` ```java package cve; import io.micronaut.context.annotation.Replaces; import io.micronaut.context.annotation.Requires; import io.micronaut.core.annotation.NonNull; import io.micronaut.core.util.StringUtils; import io.micronaut.security.config.SecurityConfigurationProperties; import io.micronaut.security.oauth2.client.IdTokenClaimsValidator; import io.micronaut.security.oauth2.configuration.OauthClientConfiguration; import io.micronaut.security.oauth2.configuration.OpenIdClientConfiguration; import io.micronaut.security.token.jwt.generator.claims.JwtClaims; import io.micronaut.security.token.jwt.validator.JwtClaimsValidatorConfigurationProperties; import javax.inject.Singleton; import java.net.URL; import java.util.Collection; import java.util.List; import java.util.Optional; @Requires(property = SecurityConfigurationProperties.PREFIX + ".authentication", value = "idtoken") @Requires(property = JwtClaimsValidatorConfigurationProperties.PREFIX + ".openid-idtoken", notEquals = StringUtils.FALSE) @Singleton @Replaces(IdTokenClaimsValidator.class) public class IdTokenClaimsValidatorReplacement extends IdTokenClaimsValidator { public IdTokenClaimsValidatorReplacement(Collection<OauthClientConfiguration> oauthClientConfigurations) { super(oauthClientConfigurations); } @Override protected boolean validateIssuerAudienceAndAzp(@NonNull JwtClaims claims, @NonNull String iss, @NonNull List<String> audiences, @NonNull String clientId, @NonNull OpenIdClientConfiguration openIdClientConfiguration) { if (openIdClientConfiguration.getIssuer().isPresent()) { Optional<URL> issuerOptional = openIdClientConfiguration.getIssuer(); if (issuerOptional.isPresent()) { String issuer = issuerOptional.get().toString(); return issuer.equalsIgnoreCase(iss) && audiences.contains(clientId) && validateAzp(claims, clientId, audiences); } } return false; } } ``

Metadata

Created: 2023-10-05T20:55:14Z
Modified: 2023-10-13T22:11:53Z
Source: https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2023/10/GHSA-qw22-8w9r-864h/GHSA-qw22-8w9r-864h.json
CWE IDs: ["CWE-284"]
Alternative ID: GHSA-qw22-8w9r-864h
Finding: F039
Auto approve: 1