Subject: [OAUTH-WG] I-D Action: draft-ietf-oauth-security-topics-10.txt

From: [email-masked]
Date: Tue, 20 Nov 2018 11:26:58 -0800

A New Internet-Draft is available from the on-line Internet-Drafts directories.
This draft is a work item of the Web Authorization Protocol WG of the IETF.

        Title           : OAuth 2.0 Security Best Current Practice
        Authors         : Torsten Lodderstedt
                          John Bradley
                          Andrey Labunets
                          Daniel Fett
	Filename        : draft-ietf-oauth-security-topics-10.txt
	Pages           : 38
	Date            : 2018-11-20

Abstract:
   This document describes best current security practice for OAuth 2.0.
   It updates and extends the OAuth 2.0 Security Threat Model to
   incorporate practical experiences gathered since OAuth 2.0 was
   published and covers new threats relevant due to the broader
   application of OAuth 2.0.

The IETF datatracker status page for this draft is:
https://datatracker.ietf.org/doc/draft-ietf-oauth-security-topics/

There are also htmlized versions available at:
https://tools.ietf.org/html/draft-ietf-oauth-security-topics-10
https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-10

A diff from the previous version is available at:
https://www.ietf.org/rfcdiff?url2=draft-ietf-oauth-security-topics-10

Please note that it may take a couple of minutes from the time of submission
until the htmlized version and diff are available at tools.ietf.org.

Internet-Drafts are also available by anonymous FTP at:
ftp://ftp.ietf.org/internet-drafts/

---

From: Torsten Lodderstedt <[email-masked]>
Date: Tue, 20 Nov 2018 20:32:50 +0100

Hi all, 

the new revision contains the following changes:

* added section on refresh tokens 
* additional justifications for recommendation for code
* refactored 2.1 in order to distinguish CSRF, authz response replay and mix-up (based on feedback by Joseph Heenan)
* added requirement to authenticate clients during code exchange (PKCE or client credential) to 2.1.1.
* changed occurrences of SHALL to MUST

As always: looking forward for your feedback.

kind regards,
Torsten. 

> Am 20.11.2018 um 20:26 schrieb [email-masked]:
> 
> 
> _______________________________________________
> OAuth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/oauth

---

From: Aaron Parecki <[email-masked]>
Date: Tue, 20 Nov 2018 12:37:34 -0800

The new section on refresh tokens is great! I have a couple
questions/comments about some of the details.

Authorization servers may revoke refresh tokens automatically in case
> of a security event, such as:
> o  logout at the authorization server

This doesn't sound like the desired behavior for mobile apps, where the
user's expectation of how long they are logged in to the mobile app is not
tied to their web session where they authorized the app. However this does
likely match a user's expectation when authorizing a browser-based app.
Should this be clarified that it should not apply to the mobile app case,
or only apply to browser-based apps?

Refresh tokens should expire if the client has been inactive for some time

This is a good suggestion, but I think it would benefit from a little more
clarity. Specifically pointing out that what counts as "activity" is use of
the access token and/or refresh token, if that's the intention. That will
help avoid confusion that "inactivity" may be referring to the user's
session at the authorization server.

Is this supposed to be a capital "SHOULD" or lowercase "should"?

It is also unclear whether this is meant to apply to public clients,
private clients, or both, as well as whether it should apply to mobile apps
or browser-based apps or both. I am curious what the intent is here, since
I feel like that can have some serious implications for the user experience
in some cases and is worth pointing out.

Lastly, minor nit, I see the comment about changing occurrences of "SHALL"
to "MUST", but the new refresh token section still has two uses of "SHALL".

Thanks! Overall I'm happy to see this guidance!

----
Aaron Parecki
aaronparecki.com

On Tue, Nov 20, 2018 at 11:33 AM Torsten Lodderstedt <
[email-masked]> wrote:

> * refactored 2.1 in order to distinguish CSRF, authz response replay and
> mix-up (based on feedback by Joseph Heenan)

---

From: George Fletcher <[email-masked]>
Date: Tue, 20 Nov 2018 17:38:13 -0500

Thanks for the additional section on refresh_tokens. Some additional 
recommendations...

1. By default refresh_tokens are bound to the user's authenticated 
session. When the authenticated session expires or is terminated 
(whether by the user or for some other reason) the refresh_tokenis 
implicitly revoked.
2. Clients that need to obtain a refresh_token that exists beyond the 
lifetime of the user's authentication session MUST indicate this need by 
requesting the "offline_access" scope 
(https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess). 
This provides for a user consent event making it clear to the user that 
the client is requesting access even when the user's authentication 
session expires. This then becomes the default for mobile apps as the 
refresh_token should not be tied to the web session used to authorize 
the app.
3. The AS MAY consider putting an upper bound on the lifetime of a 
refresh_token (e.g. 1 year). There is no real need to issue a 
refresh_token that is good indefinitely.

This is in addition to the other best practices described.

Thanks,
George

---

From: David Waite <[email-masked]>
Date: Tue, 20 Nov 2018 15:47:37 -0700

> On Nov 20, 2018, at 1:37 PM, Aaron Parecki <[email-masked]> wrote:
> 
> The new section on refresh tokens is great! I have a couple questions/comments about some of the details.
> 
> This doesn't sound like the desired behavior for mobile apps, where the user's expectation of how long they are logged in to the mobile app is not tied to their web session where they authorized the app. However this does likely match a user's expectation when authorizing a browser-based app. Should this be clarified that it should not apply to the mobile app case, or only apply to browser-based apps?

There is also the model where web sessions are perpetual; where you are evaluating access against a confidence that it is the legitimate user against known threats. In that model, you require authentication (perhaps by invalidating a client’s access and refresh tokens) as needed to rebuild that confidence.

This still is considered an online model; the offline model would be distinguished by evaluating the confidence that a client is still trusted and acting in the user’s interests.

In terms of user-initiated logout - logout is an interesting action, with both broad and miscommunicated purpose. I’ve found three different verbalizations of why a user hits this button:

1. It must be here for some reason, so I think I’m supposed to hit it when I’m done (aka 'security hygiene')
2. I suspect I might not be the next person who interacts with this device, so you should ask me who I am before allowing future access (aka ‘is this still you’)
3. I want software on this device to stop being able to access my accounts, and to destroy any cached information (aka ‘kill switch’)

All could be expected to stop access by online clients, while someone operating under expectation #3 could extend even to stopping offline access.

Likewise, it could be said that users with expectation #2 would resume access with previous scopes after an authentication, while expectation #3 would imply a need to reestablish consent to resume.

-DW

---

From: George Fletcher <[email-masked]>
Date: Tue, 20 Nov 2018 18:07:29 -0500

All important points. I'm not sure it affects whether refresh_tokens 
should be bound to the authenticated session or not. If using a 
continuous authentication model, it just means that as long as the AS/OP 
believes the authentication session is valid, the refresh_token will 
also continue to be valid. When the authentication session is determined 
to be invalid, then the refresh_token is also revoked. In this 
"continuous authentication" model, it feels like forcing the user to 
re-authenticate would be a last resort. Instead other mechanisms would 
be used to increase the confidence that the identified user is correct.

On 11/20/18 5:47 PM, David Waite wrote:
>
>
>> On Nov 20, 2018, at 1:37 PM, Aaron Parecki <[email-masked] 
>> <mailto:[email-masked]>> wrote:
>>
>> This doesn't sound like the desired behavior for mobile apps, where 
>> the user's expectation of how long they are logged in to the mobile 
>> app is not tied to their web session where they authorized the app. 
>> However this does likely match a user's expectation when authorizing 
>> a browser-based app. Should this be clarified that it should not 
>> apply to the mobile app case, or only apply to browser-based apps?
>
> There is also the model where web sessions are perpetual; where you 
> are evaluating access against a confidence that it is the legitimate 
> user against known threats. In that model, you require authentication 
> (perhaps by invalidating a client’s access and refresh tokens) as 
> needed to rebuild that confidence.
>
> This still is considered an online model; the offline model would be 
> distinguished by evaluating the confidence that a client is still 
> trusted and acting in the user’s interests.
>
> In terms of user-initiated logout - logout is an interesting action, 
> with both broad and miscommunicated purpose. I’ve found three 
> different verbalizations of why a user hits this button:
>
> 2. I suspect I might not be the next person who interacts with this 
> device, so you should ask me who I am before allowing future access 
> (aka ‘is this still you’)
> 3. I want software on this device to stop being able to access my 
> accounts, and to destroy any cached information (aka ‘kill switch’)
>
> All could be expected to stop access by online clients, while someone 
> operating under expectation #3 could extend even to stopping offline 
> access.
>
> Likewise, it could be said that users with expectation #2 would resume 
> access with previous scopes after an authentication, while expectation 
> #3 would imply a need to reestablish consent to resume.
>
> -DW
>
>

---

From: Torsten Lodderstedt <[email-masked]>
Date: Wed, 28 Nov 2018 11:07:24 +0100

Hi Aaron,

> Am 20.11.2018 um 21:37 schrieb Aaron Parecki <[email-masked]>:
> 

The Security BCP’s is intended to describe threats and potential countermeasures for implementors. There is such a variety of design option even within a class of apps, I don’t think we can cover them all. I think this kind of consideration should go into app type specific BCPs, like your’s.

Nevertheless, if you come up with a concrete text proposal, we can discuss it’s inclusion.  

> This is a good suggestion, but I think it would benefit from a little more clarity. Specifically pointing out that what counts as "activity" is use of the access token and/or refresh token, if that's the intention. That will help avoid confusion that "inactivity" may be referring to the user's session at the authorization server.

You are right. Acivity here means „refresh“. How about this:

Refresh tokens SHOULD expire if the client has been inactive for some time, 
    	i.e. the refresh token has not been used to obtain fresh access tokens for 
    	some time. The expiration time is at the discretion of the authorization server. 
    	It might be a global value or determined based on the client policy or
    	the grant associated with the refresh token (and its sensitivity).

> 
> Is this supposed to be a capital "SHOULD" or lowercase "should“?

Changed it (see above)

> It is also unclear whether this is meant to apply to public clients, private clients, or both, as well as whether it should apply to mobile apps or browser-based apps or both. I am curious what the intent is here, since I feel like that can have some serious implications for the user experience in some cases and is worth pointing out.

It’s supposed to by applicable to all sorts of clients. The text explicitly distinguishes protection mechanisms for public and confidential clients. What do you miss? Any text proposal is helpful. 

> 
> Lastly, minor nit, I see the comment about changing occurrences of "SHALL" to "MUST", but the new refresh token section still has two uses of "SHALL“.

Fixed it.

> Thanks! Overall I'm happy to see this guidance!

Thanks.

kind regards,
Torsten.

> 
> ----
> Aaron Parecki
> aaronparecki.com
> 
> 
> 
> On Tue, Nov 20, 2018 at 11:33 AM Torsten Lodderstedt <[email-masked]> wrote:
> Hi all, 
>

---

From: Torsten Lodderstedt <[email-masked]>
Date: Wed, 28 Nov 2018 11:11:42 +0100

Hi George, 

> Am 20.11.2018 um 23:38 schrieb George Fletcher <[email-masked]>:
> 
> Thanks for the additional section on refresh_tokens. Some additional recommendations...
> 
> 1. By default refresh_tokens are bound to the user's authenticated session. When the authenticated session expires or is terminated (whether by the user or for some other reason) the refresh_tokenis implicitly revoked.

SHOULD or MUST? I would suggest to go with a SHOULD.

> 2. Clients that need to obtain a refresh_token that exists beyond the lifetime of the user's authentication session MUST indicate this need by requesting the "offline_access" scope (https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess). This provides for a user consent event making it clear to the user that the client is requesting access even when the user's authentication session expires. This then becomes the default for mobile apps as the refresh_token should not be tied to the web session used to authorize the app.

Sounds reasonable, just the scope „offline_access“ is OIDC specific. Is it time to move it down the stack to OAuth?

> 3. The AS MAY consider putting an upper bound on the lifetime of a refresh_token (e.g. 1 year). There is no real need to issue a refresh_token that is good indefinitely. 

I thought I had covered that in the last section. It’s now: 

Proposals are welcome!

kind regards,
Torsten.

---

From: George Fletcher <[email-masked]>
Date: Wed, 28 Nov 2018 10:53:51 -0500

> SHOULD or MUST? I would suggest to go with a SHOULD.
I would say that the AS SHOULD bind the refresh_token to the user's 
authentication. However, I'd lean more to MUST for session bound 
refresh_tokens being revoked when the session is terminated.
> Sounds reasonable, just the scope „offline_access“ is OIDC specific. Is it time to move it down the stack to OAuth?
It may be if we want more consistency in the implementation of 
refresh_token policy across authorization servers.
>      	the grant associated with the refresh token (and its sensitivity).
This is slightly different but sufficient so +1 for the text :)

---

From: Torsten Lodderstedt <[email-masked]>
Date: Wed, 28 Nov 2018 18:19:14 +0100

> Am 28.11.2018 um 16:53 schrieb George Fletcher <[email-masked]>:
> 
> I would say that the AS SHOULD bind the refresh_token to the user's authentication. However, I'd lean more to MUST for session bound refresh_tokens being revoked when the session is terminated.

wfm 

Anyone on the list wanting to object? 

> It may be if we want more consistency in the implementation of refresh_token policy across authorization servers.

Who has an opinion on that topic?

> This is slightly different but sufficient so +1 for the text :)

Ok, thanks.

---

From: Phil Hunt <[email-masked]>
Date: Wed, 28 Nov 2018 09:36:45 -0800

Apologies, I may be speaking out of turn by not fully understanding the use cases that this thread may be focused on. I’m interpreting the conclusions you are proposing as general recommendations rather than addressing a specific case.

IMO the biggest general value of refresh is a periodic proof-of-possession demonstration by the client. It also serves as a non-user-present recovery for when access tokens are revoked for non-security reasons (e.g. for administrative reasons because token claims may change over time).  If a token were revoked due to a detected security threat, then one would presume the refresh and the grant are also revoked (not sure if this is always true).

Responses inline….

Phil

Oracle Corporation, Cloud Security and Identity Architect
@independentid
www.independentid.com <http://www.independentid.com/>[email-masked] <mailto:[email-masked]>

> On Nov 28, 2018, at 9:19 AM, Torsten Lodderstedt <[email-masked]> wrote:
> 
> 
> 

In some cases, maybe due to the nature of the client (e.g. is it a native app) you could make these assumptions. These cases are where the client becomes effectively a new type of user-agent representing the active user. The agent acts on behalf of direct user interactions.

In other cases, an independent agent is delegated some rights. For example, a web service is assigned the rights to survey bank accounts and investments to produce consolidated financial reports on a weekly basis.

These cases represent true delegated authority.  Another example, setting up long-term associations for IoT devices and apps.

> Who has an opinion on that topic?

I think this intrudes on the scope parameter which is so far, not standardized in OAuth2.  This will cause breaking changes for many.  Are there any clients that would switch between “session” mode and “offline” mode dynamically. I would assert that in most cases clients tend to be one or the other.

This would be better handled as part the client’s registration metadata.

---

From: "Richard Backman, Annabelle" <[email-masked]>
Date: Thu, 29 Nov 2018 00:20:23 +0000

I think we need to be very careful about prescribing behavior around refresh token lifetime, and setting expectations for what degree of consistency is attainable. Considering the terms "session", "authenticated session", "offline", "expiration", "termination", and "log out" can mean different things to different services (and those tiny nuances matter!) I am against text that makes binding refresh tokens to the authenticated session a "SHOULD." Rather, we should recommend that the AS provide the end user with a mechanism by which they may terminate refresh tokens. We can also describe session-bound refresh tokens as one such method that may or may not be appropriate depending on the use case.

To back up my claim that consistency is Hard, here are a few scenarios to consider:

1)
A mobile app loads the authorization request in an in-app browser tab that has an app-scoped cookie jar and is never presented by the app again after the flow is complete. How does the user sign out of that session? Should the AS kill the session due to inactivity? Won't that confuse the user when suddenly the integration between app and service stops working for no discernable reason? If this scenario sounds unlikely, it's not. This is the behavior of every app that integrated with the Safari in-app browser tab in iOS 9 and never updated to the authentication-oriented replacements introduced later, as well as that of every app that opens the authorization request in a web view (ugh).

2)
A mobile app loads the authorization request in the external browser, but the user always uses the AS's app on their device instead of visiting their website (e.g., using the Gmail app instead of going to gmail.com in the browser), so their browser session quickly times out due to inactivity. Again, won't that confuse the user when the client mobile app stops working?

3)
A set-top box uses the device flow, and the tokens it receives are bound to the user's session in the web browser on their laptop, where they completed the device flow. The user buys a new laptop, their session on their old laptop times out due to inactivity, and their set-top box can't stream videos anymore. ¯\_(ツ)_/¯

-- 
Annabelle Richard Backman
AWS Identity

On 11/28/18, 9:20 AM, "OAuth on behalf of Torsten Lodderstedt" <[email-masked] on behalf of [email-masked]> wrote:

    
    wfm 

    

    Ok, thanks.

---

From: Neil Madden <[email-masked]>
Date: Thu, 29 Nov 2018 06:18:50 +0000

Agreed. Consider also service account flows such as the JWT-bearer approach used by Google: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#authorizingrequests

It’s not clear there is any session at all in these cases. (Although I don’t think there is a refresh token in this specific case). 

I think spectrum of desired behaviours is too wide to recommend any particular option. Perhaps tying the refresh token to a session could be included as a MAY just to document it as something to consider?

— Neil

> On 29 Nov 2018, at 00:20, Richard Backman, Annabelle <richanna=[email-masked]> wrote:
>

---

From: Brian Campbell <[email-masked]>
Date: Thu, 29 Nov 2018 13:22:36 -0700

Big +1 here. I'd be in favor of the document discussing the potential
benefits of tying the refresh token to a session in some situations but
very much agree that the spectrum of desired behaviors is much too wide to
normatively recommend any particular option.

On Wed, Nov 28, 2018 at 11:19 PM Neil Madden <[email-masked]>
wrote:

> Agreed. Consider also service account flows such as the JWT-bearer
> approach used by Google:
> https://developers.google.com/identity/protocols/OAuth2ServiceAccount#authorizingrequests
>
> It’s not clear there is any session at all in these cases. (Although I
> don’t think there is a refresh token in this specific case).
>
> I think spectrum of desired behaviours is too wide to recommend any
> particular option. Perhaps tying the refresh token to a session could be
> included as a MAY just to document it as something to consider?
>
> — Neil
>
> On 29 Nov 2018, at 00:20, Richard Backman, Annabelle <
> richanna=[email-masked]> wrote:
>
> I think we need to be very careful about prescribing behavior around
> refresh token lifetime, and setting expectations for what degree of
> consistency is attainable. Considering the terms "session", "authenticated
> session", "offline", "expiration", "termination", and "log out" can mean
> different things to different services (and those tiny nuances matter!) I
> am against text that makes binding refresh tokens to the authenticated
> session a "SHOULD." Rather, we should recommend that the AS provide the end
> user with a mechanism by which they may terminate refresh tokens. We can
> also describe session-bound refresh tokens as one such method that may or
> may not be appropriate depending on the use case.
>
> A mobile app loads the authorization request in an in-app browser tab that
> has an app-scoped cookie jar and is never presented by the app again after
> the flow is complete. How does the user sign out of that session? Should
> the AS kill the session due to inactivity? Won't that confuse the user when
> suddenly the integration between app and service stops working for no
> discernable reason? If this scenario sounds unlikely, it's not. This is the
> behavior of every app that integrated with the Safari in-app browser tab in
> iOS 9 and never updated to the authentication-oriented replacements
> introduced later, as well as that of every app that opens the authorization
> request in a web view (ugh).
>
> 2)
> A mobile app loads the authorization request in the external browser, but
> the user always uses the AS's app on their device instead of visiting their
> website (e.g., using the Gmail app instead of going to gmail.com in the
> browser), so their browser session quickly times out due to inactivity.
> Again, won't that confuse the user when the client mobile app stops working?
>
> 3)
> A set-top box uses the device flow, and the tokens it receives are bound
> to the user's session in the web browser on their laptop, where they
> completed the device flow. The user buys a new laptop, their session on
> their old laptop times out due to inactivity, and their set-top box can't
> stream videos anymore. ¯\_(ツ)_/¯
>
> --
> On 11/28/18, 9:20 AM, "OAuth on behalf of Torsten Lodderstedt" <
> [email-masked] on behalf of [email-masked]> wrote:
>
>
>
> session. When the authenticated session expires or is terminated (whether
> by the user or for some other reason) the refresh_tokenis implicitly
> revoked.
>
> requesting the "offline_access" scope (
> https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess)..
> This provides for a user consent event making it clear to the user that the
> client is requesting access even when the user's authentication session
> expires. This then becomes the default for mobile apps as the refresh_token
> should not be tied to the web session used to authorize the app.
>
> refresh_token (e.g. 1 year). There is no real need to issue a refresh_token
> that is good indefinitely.
>
> Am 20.11.2018 um 20:26 schrieb [email-masked]
>
> :
>
>
>
>  This document describes best current security practice for OAuth 2.0..
>
> <https://www..ietf.org/rfcdiff?url2=draft-ietf-oauth-security-topics-10>
>
>
>
>
> https://www..ietf.org/mailman/listinfo/oauth
> <https://www.ietf.org/mailman/listinfo/oauth>
>
>

-- 
_CONFIDENTIALITY NOTICE: This email may contain confidential and privileged 
material for the sole use of the intended recipient(s). Any review, use, 
distribution or disclosure by others is strictly prohibited.  If you have 
received this communication in error, please notify the sender immediately 
by e-mail and delete the message and any file attachments from your 
computer. Thank you._