Lucene search

K
osvGoogleOSV:GHSA-QW22-8W9R-864H
HistoryOct 05, 2023 - 8:55 p.m.

io.micronaut.security:micronaut-security-oauth2 has invalid IdTokenClaimsValidator logic on aud

2023-10-0520:55:14
Google
osv.dev
4
micronaut-security-oauth2
idtokenclaimsvalidator
audience
oidc
upgrade
patch

6.5 Medium

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

LOW

Integrity Impact

LOW

Availability Impact

NONE

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

7 High

AI Score

Confidence

Low

0.0005 Low

EPSS

Percentile

17.0%

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:

                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

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;
    }
}
``

6.5 Medium

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

LOW

Integrity Impact

LOW

Availability Impact

NONE

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

7 High

AI Score

Confidence

Low

0.0005 Low

EPSS

Percentile

17.0%

Related for OSV:GHSA-QW22-8W9R-864H