Subject: [Id-event] Distinguishing different JWT types

From: William Denniss <[email-masked]>
Date: Wed, 4 Nov 2015 14:19:01 +0900

Hi Everyone,

It was good talking to many of you at Yokohama earlier in the week about
using JWTs for event messages like Logout, Risk Signals, SCIM profile
updates and more. Thank you Phil for starting this conversation and
spinning up the list! We're all doing related things with events, and it
makes sense to collaborate and unify our approaches.

An issue with JWT reuse currently is that ID Tokens are defined
<http://openid.net/specs/openid-connect-core-1_0.html#IDToken> by OpenID
Connect to require only a few standard JWT claims
<https://tools.ietf.org/html/rfc7519#section-4>, and the required claims
are highly re-usable and contain nothing that actually sets them apart as
an "ID Token".

The risk of this is that a JWT for an event like logout can be a valid ID
Token for login.  An attacker in possession of a logout token could replay
it against a login endpoint, and gain access.

One mitigation is to change the issuer, or audience. To me this is
undesirable as the events (e.g. logout) do relate to the same issuer and
audience. Like matter and anti-matter, yin and yang – logout should simply
reverse the login.  It seems wasteful to spin up a new issuer, new key
rotations, and more just to manage each different type of event, if they
would otherwise be related by issuer.

Currently the Backchannel Logout draft
<http://openid.net/specs/openid-connect-backchannel-1_0.html> attempts to
"break" this utility of a logout JWT for authentication by prohibiting
the 'nonce' field:

The following Claim MUST NOT be used within the Logout Token:

noncePROHIBITED. A nonce Claim MUST NOT be present. Its use is prohibited
to make a Logout Token syntactically invalid if used in a forged
Authentication Response in place of an ID Token.

I'm concerned that this may not always work as intended, as 'nonce' is not
a required field of the ID Token. ID Tokens obtained from Google using the
code flow (on our OpenID Connect certified endpoints) do not contain
'nonce' today, for example. And I'm a little worried that RPs may not be
strictly checking for a 'nonce', even when they should (e.g. when using the
implicit flow).

Even if this approach works in this specific case, it's not scalable. So I
propose that we move to adopt a new standard claim that can be used to
indicate the intended purpose of the JWT.

'typ' is an obvious choice for a claim name, although the word 'type' may
be a little overloaded already. Another option could be "cat" for
category.  Whatever we decide, I think such a claim should be used in all
JWT specs going forward, and added to OpenID Connect ID Tokens in a future
revision.

William

---

From: Justin Richer <[email-masked]>
Date: Wed, 4 Nov 2015 14:36:44 +0900

I think a real question with regard to the login/logout case is, succinctly, “Why is an application accepting an ID token from an unknown third-party as proof of login”? In the normal OIDC process, the client will only get the ID token in response to an authentication request, so it shouldn’t ever be just listening for incoming ID tokens.

 — Justin

> On Nov 4, 2015, at 2:19 PM, William Denniss <[email-masked]> wrote:
> 
> Hi Everyone,
> 
> It was good talking to many of you at Yokohama earlier in the week about using JWTs for event messages like Logout, Risk Signals, SCIM profile updates and more. Thank you Phil for starting this conversation and spinning up the list! We're all doing related things with events, and it makes sense to collaborate and unify our approaches.
> 
> An issue with JWT reuse currently is that ID Tokens are defined <http://openid.net/specs/openid-connect-core-1_0.html#IDToken> by OpenID Connect to require only a few standard JWT claims <https://tools.ietf.org/html/rfc7519#section-4>, and the required claims are highly re-usable and contain nothing that actually sets them apart as an "ID Token".
> 
> The risk of this is that a JWT for an event like logout can be a valid ID Token for login.  An attacker in possession of a logout token could replay it against a login endpoint, and gain access.
> 
> One mitigation is to change the issuer, or audience. To me this is undesirable as the events (e.g. logout) do relate to the same issuer and audience. Like matter and anti-matter, yin and yang – logout should simply reverse the login.  It seems wasteful to spin up a new issuer, new key rotations, and more just to manage each different type of event, if they would otherwise be related by issuer.
> 
> Currently the Backchannel Logout draft <http://openid.net/specs/openid-connect-backchannel-1_0.html> attempts to "break" this utility of a logout JWT for authentication by prohibiting the 'nonce' field:
> nonce
> PROHIBITED. A nonce Claim MUST NOT be present. Its use is prohibited to make a Logout Token syntactically invalid if used in a forged Authentication Response in place of an ID Token.
> 
> I'm concerned that this may not always work as intended, as 'nonce' is not a required field of the ID Token. ID Tokens obtained from Google using the code flow (on our OpenID Connect certified endpoints) do not contain 'nonce' today, for example. And I'm a little worried that RPs may not be strictly checking for a 'nonce', even when they should (e.g. when using the implicit flow).
> 
> Even if this approach works in this specific case, it's not scalable. So I propose that we move to adopt a new standard claim that can be used to indicate the intended purpose of the JWT.
> 
> 'typ' is an obvious choice for a claim name, although the word 'type' may be a little overloaded already. Another option could be "cat" for category.  Whatever we decide, I think such a claim should be used in all JWT specs going forward, and added to OpenID Connect ID Tokens in a future revision.
> 
> William
> 
> 
> 
> _______________________________________________
> Id-event mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/id-event

---

From: John Bradley <[email-masked]>
Date: Wed, 4 Nov 2015 16:01:27 +0900

In principal a client gets a token two ways.  
1 via a token endpoint in a direct communication.
2 via the authorization endpoint, In this case a client needs to check the nonce value to correlate the token with the user agent that the request was made via.

I think it is fair not to have a nonce in the other tokens as they are not requested via the browser.  Nonce would also not be appropriate for a JWT assertion.

I would be more worried about other sorts of assertions being confused, or at-least not easily differentiated. 

I don’t think having a explicit JWT token type being a bad thing.   Adding it would not disrupt existing clients.  

I think it is more a case of determining if this will be useful for other things.   In connect it would really only help badly coded clients who are unlikely to check it anyway.

John B.

> On Nov 4, 2015, at 2:36 PM, Justin Richer <[email-masked] <mailto:[email-masked]>> wrote:
> 
>> On Nov 4, 2015, at 2:19 PM, William Denniss <[email-masked] <mailto:[email-masked]>> wrote:
>> 
>> Hi Everyone,
>> 
>> [email-masked] <mailto:[email-masked]>
>> https://www.ietf.org/mailman/listinfo/id-event <https://www.ietf.org/mailman/listinfo/id-event>
> 
> [email-masked] <mailto:[email-masked]>

---

From: John Bradley <[email-masked]>
Date: Wed, 4 Nov 2015 16:06:03 +0900

John B.

---

From: Justin Richer <[email-masked]>
Date: Wed, 4 Nov 2015 16:24:50 +0900

I’m very much in favor of having a JWT token type key, but for other reasons and uses. 

I’m just taking issue with the assertion that a logout token could be easily confused by a functioning OIDC client.

Even then I think it’s a good idea to have a “typ": “logout” tag in it. The current guideline to take the “nonce” out is a profoundly stupid hack that’s not likely to make much difference in the real world, or at least even less of a difference than a type parameter.

Along those lines, I’d suggest we use “jtt" or “JSON (web) Token Type” as the field name, so we don’t cause confusion with the header “typ” parameter.

 — Justin

> On Nov 4, 2015, at 4:06 PM, John Bradley <[email-masked]> wrote:
>

---

From: John Bradley <[email-masked]>
Date: Wed, 4 Nov 2015 16:41:45 +0900

Nonce is only required for tokens being delivered in the front channel.   Saying don’t try to store it on the server side to send as part of the backchannel logout where it makes no sense, and that the client shouldn't look for it to verify, is reasonable.   

I agree that characterizing it as a way to keep a token from being accepted in the implicit flow is probably confusing.

It is true that as it is now, a client MUST not take a id_token in the front channel with a missing or invalid nonce.   Unfortunately that may not be perfectly implemented in all clients.

The various possible distribution methods for these other sorts of tokens may have different security characteristics and may not be kept perfectly secret via a hub etc.

Those tokens should not be accepted in the front channel no matter what there claims as long as the client implements nonce correctly.

John B.

> On Nov 4, 2015, at 4:24 PM, Justin Richer <[email-masked]> wrote:
> 
>> On Nov 4, 2015, at 4:06 PM, John Bradley <[email-masked] <mailto:[email-masked]>> wrote:
>>

---

From: William Denniss <[email-masked]>
Date: Wed, 4 Nov 2015 16:53:45 +0900

Fair points. My main concern is that we don't always know how people treat
ID Tokens (or JWTs more generally), and one of their nice properties is
that they are designed to be verifiable if transmitted over an untrusted
medium.

I think we can build in more protection going forward by having a clear
type indicator. Imagine having 6 different JWT types, all potentially
validating as the other types. It seems dangerous if the only protection is
that they shouldn't be accepted outside their intended flows, and also
downright confusing as they all look similar.

Removing fields to break potential re-use doesn't scale, and doesn't help
understandability either.

On Wed, Nov 4, 2015 at 4:24 PM, Justin Richer <[email-masked]> wrote:

> I’m just taking issue with the assertion that a logout token could be
> easily confused by a functioning OIDC client.
>
> Even then I think it’s a good idea to have a “typ": “logout” tag in it.
> The current guideline to take the “nonce” out is a profoundly stupid hack
> that’s not likely to make much difference in the real world, or at least
> even less of a difference than a type parameter.
>
> Along those lines, I’d suggest we use “jtt" or “JSON (web) Token Type” as
> the field name, so we don’t cause confusion with the header “typ” parameter.
>
>  — Justin
>
> 2 via the authorization endpoint, In this case a client needs to check the
> nonce value to correlate the token with the user agent that the request was
> made via.
>
> I think it is fair not to have a nonce in the other tokens as they are not
> requested via the browser.  Nonce would also not be appropriate for a JWT
> assertion.
>
> I think it is more a case of determining if this will be useful for other
> things.   In connect it would really only help badly coded clients who are
> unlikely to check it anyway.
>
> John B.
>
> On Nov 4, 2015, at 2:36 PM, Justin Richer <[email-masked]> wrote:
>
> I think a real question with regard to the login/logout case is,
> succinctly, “Why is an application accepting an ID token from an unknown
> third-party as proof of login”? In the normal OIDC process, the client will
> only get the ID token in response to an authentication request, so it
> shouldn’t ever be just listening for incoming ID tokens.
>
>  — Justin
>

---

From: Mike Jones <[email-masked]>
Date: Wed, 4 Nov 2015 08:04:38 +0000

The part of this thread dealing with logout should have included a reference to this text in http://openid.net/specs/openid-connect-backchannel-1_0-01.html#LogoutToken:

logout_only
REQUIRED. Value declaring that this JWT is only to be used as a Logout Token. In particular, this JWT cannot be used in any context where an ID Token is used. The value of this Claim MUST be the JSON boolean value true.

This claim is currently used to “type” the logout token.  Changing from “logout_only”:true to “jty”: “logout” or something similar would be fine.

John suggested that we prohibit the inclusion of “nonce” as a second way of ensuring that that token couldn’t be repurposed as an ID Token.  That would work even if the code wasn’t checking for “logout_only” or “jty”.

                                                            -- Mike

From: Id-event [mailto:[email-masked]] On Behalf Of William Denniss
Sent: Wednesday, November 04, 2015 4:54 PM
To: Justin Richer
Cc: John Bradley; [email-masked]
Subject: Re: [Id-event] Distinguishing different JWT types

Fair points. My main concern is that we don't always know how people treat ID Tokens (or JWTs more generally), and one of their nice properties is that they are designed to be verifiable if transmitted over an untrusted medium.

I think we can build in more protection going forward by having a clear type indicator. Imagine having 6 different JWT types, all potentially validating as the other types. It seems dangerous if the only protection is that they shouldn't be accepted outside their intended flows, and also downright confusing as they all look similar.

Removing fields to break potential re-use doesn't scale, and doesn't help understandability either.

On Wed, Nov 4, 2015 at 4:24 PM, Justin Richer <[email-masked]<mailto:[email-masked]>> wrote:
I’m very much in favor of having a JWT token type key, but for other reasons and uses.

 — Justin

On Nov 4, 2015, at 4:06 PM, John Bradley <[email-masked]<mailto:[email-masked]>> wrote:

John B.

On Nov 4, 2015, at 2:36 PM, Justin Richer <[email-masked]<mailto:[email-masked]>> wrote:

 — Justin

On Nov 4, 2015, at 2:19 PM, William Denniss <[email-masked]<mailto:[email-masked]>> wrote:

Hi Everyone,

An issue with JWT reuse currently is that ID Tokens are defined<http://openid.net/specs/openid-connect-core-1_0.html#IDToken> by OpenID Connect to require only a few standard JWT claims<https://tools.ietf.org/html/rfc7519#section-4>, and the required claims are highly re-usable and contain nothing that actually sets them apart as an "ID Token".

Currently the Backchannel Logout draft<http://openid.net/specs/openid-connect-backchannel-1_0.html> attempts to "break" this utility of a logout JWT for authentication by prohibiting the 'nonce' field:

nonce

William

_______________________________________________
Id-event mailing list
[email-masked]<mailto:[email-masked]>
https://www.ietf.org/mailman/listinfo/id-event

_______________________________________________
Id-event mailing list
[email-masked]<mailto:[email-masked]>
https://www.ietf.org/mailman/listinfo/id-event

---

From: Mike Jones <[email-masked]>
Date: Wed, 4 Nov 2015 08:09:11 +0000

Some of you have seen my remark below but I’m resending it to get it on the record for those of you have not…

I want to stay completely clear of situations in which multiple kinds of messages are sent to the same endpoint and then dispatched to do different things based on the message type.  That is the pattern that led people to abandon SOAP/WS-* for REST.  I don’t want to be part of recreating it.

For instance, I only want logout message to be sent to the OpenID Connect logout endpoint.  It’s appropriate for the endpoint to *validate* that the message conforms to the specified logout message syntax and otherwise reject the message.  But the only action taken for messages of other types should be to drop them – not dispatch them.

                                                            -- Mike

From: Id-event [mailto:[email-masked]] On Behalf Of Mike Jones
Sent: Wednesday, November 04, 2015 5:05 PM
To: William Denniss; Justin Richer
Cc: John Bradley; [email-masked]
Subject: Re: [Id-event] Distinguishing different JWT types

logout_only

                                                            -- Mike

From: Id-event [mailto:[email-masked]] On Behalf Of William Denniss
Sent: Wednesday, November 04, 2015 4:54 PM
To: Justin Richer
Cc: John Bradley; [email-masked]<mailto:[email-masked]>
Subject: Re: [Id-event] Distinguishing different JWT types

 — Justin

John B.

 — Justin

Hi Everyone,

nonce

William

---

From: William Denniss <[email-masked]>
Date: Wed, 4 Nov 2015 17:16:38 +0900

Sounds good to me, I like that "jty":"logout" is more extensible than
"logout_only":true

I support trying to prevent repurposing of the backchannel logout JWT, and
not including "nonce" seems reasonable. It just makes me wish OIDC ID
Tokens had a "jty":"id_token" claim, as that is a lot more clear.  Going
forward, each new token type shouldn't be removing claims other types use
just to break potential cross-type usage, hence why I proposed this.

btw. I was also thinking of 'jty' ("JWT Type") as the claim name. Reads
well to me, and isn't ambiguous :)

On Wed, Nov 4, 2015 at 5:04 PM, Mike Jones <[email-masked]>
wrote:

> The part of this thread dealing with logout should have included a
> reference to this text in
> http://openid.net/specs/openid-connect-backchannel-1_0-01.html#LogoutToken
> :
>
>
>
> logout_only
>
> REQUIRED. Value declaring that this JWT is only to be used as a Logout
> Token. In particular, this JWT cannot be used in any context where an ID
> Token is used. The value of this Claim MUST be the JSON boolean value true.
>
>
>
>
> This claim is currently used to “type” the logout token.  Changing from
> “logout_only”:true to “jty”: “logout” or something similar would be fine.
>
>
>
> John suggested that we prohibit the inclusion of “nonce” as a second way
> of ensuring that that token couldn’t be repurposed as an ID Token.  That
> would work even if the code wasn’t checking for “logout_only” or “jty”.
>
>
>
>                                                             -- Mike
>
>
>
> *From:* Id-event [mailto:[email-masked]] *On Behalf Of *William
> Denniss
> *Sent:* Wednesday, November 04, 2015 4:54 PM
> *To:* Justin Richer
> *Cc:* John Bradley; [email-masked]
> *Subject:* Re: [Id-event] Distinguishing different JWT types
>
>
>
> PROHIBITED. A nonce Claim MUST NOT be present. Its use is prohibited to
> make a Logout Token syntactically invalid if used in a forged

---

From: Nat Sakimura <[email-masked]>
Date: Wed, 4 Nov 2015 17:17:16 +0900

When I proposed type, which morephed into typ and cty, I meant what you
discribe here - an indication of what the token is. It was kind of rejecte
being an application layer stuff, which is a fair point in a sense but we
have limited ourselves apparently. +1 to something that represent its type.
In Web Linking term, something akin of "self".

Nat

2015-11-04 16:53 GMT+09:00 William Denniss <[email-masked]>:

>> 2 via the authorization endpoint, In this case a client needs to check
>> the nonce value to correlate the token with the user agent that the request
>> was made via.
>>
>> I think it is fair not to have a nonce in the other tokens as they are
>> not requested via the browser.  Nonce would also not be appropriate for a
>> JWT assertion.
>>
>> I don’t think having a explicit JWT token type being a bad thing.
>> Adding it would not disrupt existing clients.
>>
>> <http://openid.net/specs/openid-connect-backchannel-1_0.html> attempts
>> to "break" this utility of a logout JWT for authentication by prohibiting
>> the 'nonce' field:
>>
>> noncePROHIBITED. A nonce Claim MUST NOT be present. Its use is
>> prohibited to make a Logout Token syntactically invalid if used in a forged
>> I'm concerned that this may not always work as intended, as 'nonce' is
>> not a required field of the ID Token. ID Tokens obtained from Google using
>> the code flow (on our OpenID Connect certified endpoints) do not contain
>> Even if this approach works in this specific case, it's not scalable. So
>> I propose that we move to adopt a new standard claim that can be used to

-- 
Nat Sakimura (=nat)
Chairman, OpenID Foundation
http://nat.sakimura.org/
@_nat_en

---

From: John Bradley <[email-masked]>
Date: Wed, 4 Nov 2015 17:18:54 +0900

nonce is used to bind the token to a browser instance for delivery in the front channel.  Perhaps at some point Token binding will make it redundant, but it is the best we have at this point.

It makes no sense to have it in backchannel assertions or unsolicited assertions.

To my mind not including nonce is just stopping people from doing nonsensical things that may be confusing to debug.  

The IdP doesn’t currently need to maintain the nonce value beyond issuing the id_token.   Saving the nonce value to put it in a id_token a day or week later provides no value.

Even if a IdP puts nonce in the token, the client will reject it if the value is incorrect for a new authentication, different browser. 

I guess a attacker could get a logout token and somehow send it to the client via redirect assuming they can get a correct state value.
They would however be logging the correct user back in, and there are probably simpler attacks to try and do that via kicking off a login via cross site scripting.

I don’t think precluding nonce is a foolproof security measure to differentiate the tokens, but validating it is important for front channel delivered tokens.

John B.
> On Nov 4, 2015, at 5:04 PM, Mike Jones <[email-masked]> wrote:
> 
> The part of this thread dealing with logout should have included a reference to this text inhttp://openid.net/specs/openid-connect-backchannel-1_0-01.html#LogoutToken <http://openid.net/specs/openid-connect-backchannel-1_0-01.html#LogoutToken>:
>  
> logout_only
> On Wed, Nov 4, 2015 at 4:24 PM, Justin Richer <[email-masked] <mailto:[email-masked]>> wrote: