Re: [OAUTH-WG] draft-parecki-oauth-browser-based-apps-00

Torsten Lodderstedt <torsten@lodderstedt.net> Thu, 15 November 2018 20:58 UTC

Return-Path: <torsten@lodderstedt.net>
X-Original-To: oauth@ietfa.amsl.com
Delivered-To: oauth@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 7EBB2130DE4 for <oauth@ietfa.amsl.com>; Thu, 15 Nov 2018 12:58:26 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.599
X-Spam-Level:
X-Spam-Status: No, score=-2.599 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7ylTbx1wtGZt for <oauth@ietfa.amsl.com>; Thu, 15 Nov 2018 12:58:22 -0800 (PST)
Received: from smtprelay05.ispgateway.de (smtprelay05.ispgateway.de [80.67.18.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 9248B130DD8 for <oauth@ietf.org>; Thu, 15 Nov 2018 12:58:22 -0800 (PST)
Received: from [91.13.153.47] (helo=[192.168.71.123]) by smtprelay05.ispgateway.de with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from <torsten@lodderstedt.net>) id 1gNOiQ-00053y-Np; Thu, 15 Nov 2018 21:58:18 +0100
From: Torsten Lodderstedt <torsten@lodderstedt.net>
Message-Id: <7A852312-B129-4A0F-9914-8DC7E63FD12C@lodderstedt.net>
Content-Type: multipart/signed; boundary="Apple-Mail=_E820659C-4CDF-4324-AEE7-B99A956F3012"; protocol="application/pkcs7-signature"; micalg="sha-256"
Mime-Version: 1.0 (Mac OS X Mail 12.1 \(3445.101.1\))
Date: Thu, 15 Nov 2018 20:27:07 +0100
In-Reply-To: <27627bee-aaab-44fd-9821-b58f7b33bc13@getmailbird.com>
Cc: Aaron Parecki <aaron@parecki.com>, Hannes Tschofenig <hannes.tschofenig@arm.com>, oauth@ietf.org
To: Brock Allen <brockallen@gmail.com>
References: <VI1PR0801MB211299BED6B61582DC33B873FACB0@VI1PR0801MB2112.eurprd08.prod.outlook.com> <CAGBSGjqHKVveZor-oKUWzsQ0Rg5Fk_d2dns_eQFqfvXJynyQaQ@mail.gmail.com> <9347fff8-f3b9-4ee9-84d3-5eebc8dd13f4@getmailbird.com> <309DAA7D-E9B9-4A89-B30E-5BE37DC6CC85@lodderstedt.net> <27627bee-aaab-44fd-9821-b58f7b33bc13@getmailbird.com>
X-Mailer: Apple Mail (2.3445.101.1)
X-Df-Sender: dG9yc3RlbkBsb2RkZXJzdGVkdC5uZXQ=
Archived-At: <https://mailarchive.ietf.org/arch/msg/oauth/JS_fZLJepZ0js-LCUoM-65UoyBU>
Subject: Re: [OAUTH-WG] draft-parecki-oauth-browser-based-apps-00
X-BeenThere: oauth@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: OAUTH WG <oauth.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/oauth>, <mailto:oauth-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/oauth/>
List-Post: <mailto:oauth@ietf.org>
List-Help: <mailto:oauth-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/oauth>, <mailto:oauth-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 15 Nov 2018 20:58:27 -0000

Hi Brock, 

> Am 15.11.2018 um 15:01 schrieb Brock Allen <brockallen@gmail.com>:
> 
> > Helps to prevent leakage, not injection in the authorization response.
> 
> So then wording and its motivation could get updated to correctly reflect that.
> 
> >> "OAuth 2.0 provides no mechanism for a client to verify that an access token was issued to it, which could lead to misuse and possible impersonation attacks if a malicious party hands off an access token it retrieved through some other means to the client."
> >> 
> >> Sure, but OIDC does provide a mitigation for this (even with implicit).
> >
> >This is about token replay detection at the RS. What mitigation does OIDC provide here? 
> 
> The wording doesn't go with that, then. My point about OIDC is that with the at_hash in the id_token provides a mitigation so the client can verify that the access token was issued to it.

Understand, you are referring to the token injection prevention provided by „token id_token“ or „code token id_token“. It still lacks the ability to issue sender constraint access tokens. So if you wanna take the risk associated with bearer tokens you can use it. The Security BCP recommends to use sender constraint access tokens, so we cannot recommend response types not supporting this pattern. 

> 
> > The implicit grant was not equipped with the ability to issue refresh tokens simply because the working group didn’t want them to end up in the browser history, leak through open redirectors etc. This is different with code since tokens travel directly through a TLS protected connection.
> 
> Well, if limiting the access token renewal to the user's session lifetime wasn't a conscious design goal, it's a very interesting side effect which does limit the potential of an attacker.

That’s true. Note that the effectiveness of limitation depends on the lifetime of the issued access tokens. 

The AS can bind the lifetime of the refresh tokens to the session lifetime, i.e. automatically revoke it on logout. 

In my opinion, whether this is the most appropriate choice largely depends on what the client uses the token for. If the client effectively relies on the AS (OP) to login the user and obtain user data that makes sense. If the client has an independent login and uses the tokens to access resources (e.g. contacts), the session with the AS does not have  a real meaning with respect to this client. Potentially the client even stores the refresh token in a backend with the user account. 

> 
> > First of all the AS decides whether it issues refresh tokens or not. Having the ability does not mean the AS must do it. If you feel it’s safer to not do it. Fine. 
> 
> Sure, and this should be mentioned then somewhere (either in the threats doc or in this proposed best practice doc). Not all end developers using these protocols fully understand the ramifications. 

@Aaron: I suggest this goes to the SPA BCP since this is client specific.

> 
> > It’s still possible to refresh your access tokens the way you mentioned above by sending another authorization request to the AS. 
> 
> This also could be added as a proposal for an alternative to renewing tokens. It provides more awareness to folks, and aids in a potential best practice depending on the requirements of the consuming app.

I agree. 

> 
> > But let’s assume for a moment the AS, based on its risk assessment, decides to issue refresh tokens. Can you please explain how an attacker will get access to this tokens? Especially what the expected strength of the attacker would need to be?
> 
> I don't have a profile of an attack. But I'm assuming it's no different than anything in the past we've been trying to defend against when we considered the potential for an access token to be exfiltrated. So my point is that an access token will expire so an attacker would then have to go back and re-attack the app to get a new access token to continue to have access to the user's resource. But now with refresh tokens in the picture, the attacker would have both and then not need to go back to the app to continue to have access to the user's resource. 

Largely depends on the refresh token protection. I case of public clients I would always recommend to rotation refresh tokens with every refresh. This renders the old refresh tokens useless. If the attacker happens to be at the lucky end and conducts the first refresh, the AS should be able to detect the replay when the legit user tries to refresh. It then shall revoke the active (in possession of the attacker) refresh token as well. 

I will add this to the Security BCP.

> 
> > I would also like to understand how a refresh token is any different from a long living cookie in the browser and what you think is the big difference to mobile apps when it comes to refresh token handling. 
> 
> To use the cookie, the app must be active, and the attacker must be attacking the app itself.
> 
> Maybe a different way to say it is that an attacker must only compromise the app once to have long lived access, whereas without refresh tokens the attacker can attack the app once, but the once the comprised access token is expired they would have to re-attack the app to get another access token. Refresh tokens means they only have to get in once to the app, then they no longer have to go back to the source. Maybe there's a better way to convey what I'm trying to say…

I think I understand. Refresh tokens can be used outside of the user agent. Token rotation and expiration would be potential mitigations, token binding too.

> 
> Also, I guess my question/comment about providing guidance for existing implicit flow clients is not up for discussion? Again, my reasoning is that it's a hard sell to always say there's exactly one right way to do something. And since so many clients have been built based on implicit flow that might not be able to change quickly to a new flow, perhaps there are "baby steps" that can be suggested to help them improve their security.

The only potential „baby step“ I would see is to move towards „token id_token“. Since this requires signature/at_hash checks etc. I doubt this is really easier than moving to code and exchange the code for an access token. What’s your opinion?

kind regards,
Torsten. 

> 
> -Brock
>