OPAudienceInjectionAttackMitigation

OPAudienceInjectionAttackMitigation

Files: conf/relying-partyxml
Format: Native Spring

Overview

An Audience Injection Attack for, amongst others, private key JWT client authentication is discussed in a research paper. The paper outlines a mitigation strategy. This strategy involves setting the value of the audience (aud) claim in a JWT assertion to match the issuer identifier of the OP instead of the token (or target) endpoint URL. This approach is also suggested by the draft RFC.

Mitigation for v4.3.0+

OP v4.3.0 provides new profile configuration options to easily enforce the suggested changes:

  • useTargetedEndpointAsJWTAudience: Flag to enable use of endpoints (the token or target endpoint) in the JWT client authentication audience (defaults to true)

  • requireSingleJWTAudience: Flag to require single value in the JWT client authentication audience (defaults to false)

  • clientAuthenticationJWTType: Mandatory value for the typ header used within JWT authentication (default to null, meaning any or missing value is accepted)

The first two options are also available as global properties:

  • idp.oauth2.jwtAuth.targetedEndpointAsJWTAudience (defaults to true)

  • idp.oauth2.jwtAuth.requireSingleJWTAudience (defaults to false)

Mitigation for older versions

For older versions, the following methods can be used for preventing the use of token (or target) endpoint URL as the audience:

Globally for all RPs

  1. Define the following kind of bean in the conf/relying-party.xml:

    1. <bean id="StrictAudienceValidator" class="net.shibboleth.oidc.security.jwt.claims.impl.AudienceClaimsValidator" p:extraAudienceValidation="true"> <property name="audienceLookupStrategy"> <bean parent="shibboleth.BiFunctions.Constant" c:target="#{getObject('shibboleth.oidc.issuer')}" /> </property> </bean>
  2. Wire the bean as the custom JWT authentication audience validator in conf/oidc.properties:

    1. idp.oauth2.jwtAuth.audienceValidator = StrictAudienceValidator

Per-RP and -Profile basis

  1. Define the following bean in the conf/relying-party.xml:

    1. <bean id="CustomJWTClaimsValidator" class="net.shibboleth.oidc.security.jwt.claims.impl.ChainingJWTClaimsValidator"> <property name="claimValidators"> <util:list id="CustomClaimsValidators" value-type="net.shibboleth.oidc.jwt.claims.ClaimsValidator"> <ref bean="ExpiryClaimsValidator" /> <ref bean="NotBeforeClaimsValidator" /> <ref bean="IssuedAtClaimsValidator" /> <ref bean="IssuerClaimsValidator" /> <ref bean="SubjectClaimsValidator" /> <bean class="net.shibboleth.oidc.security.jwt.claims.impl.AudienceClaimsValidator" p:extraAudienceValidation="true"> <property name="audienceLookupStrategy"> <bean parent="shibboleth.BiFunctions.Constant" c:target="#{getObject('shibboleth.oidc.issuer')}" /> </property> </bean> <ref bean="JWTIdentifierClaimsValidator" /> </util:list> </property> </bean>
  2. Wire the bean to the desired profiles (possibly to specific RPs via shibboleth.RelyingPartyOverrides) in the following way. The applicable profile beans are OIDC.SSO, OAUTH2.PAR, OAUTH2.Token and OAUTH2.Introspection) together with their -MDDriven variants).

    1. ... <bean parent="OAUTH2.Token.MDDriven" p:claimsValidator-ref="CustomJWTClaimsValidator" /> <bean parent="OAUTH2.Introspection.MDDriven" p:claimsValidator-ref="CustomJWTClaimsValidator" /> ...