Subject: [OAUTH-WG] FW: draft-ietf-oauth-device-flow: url with code

From: "Manger, James" <[email-masked]>
Date: Wed, 1 Mar 2017 00:23:51 +0000

Resending; not sure that OAuth email list is working at the moment.

From: Manger, James
Sent: Tuesday, 28 February 2017 9:53 AM
To: [email-masked]
Subject: draft-ietf-oauth-device-flow: url with code

How about combining the verification_uri and user_code?

The Device Flow provides a verification_uri and user_code, both of which have to be copied to a web browser on, say, a mobile phone. The main model in this draft is that the user copies the uri, then the resulting web page prompts for the code. The draft also mentions other possibilities such as Bluetooth to do the “copying”. Transmitting a URI via Bluetooth, or NFC, or QR code, is quite common. In such cases it would be nicer to transmit the user_code as part of the URI.

Perhaps both modes could be supported by saying the user_code can be included as a query parameter on the verification_uri when it is more convenient for a device to transmit a single URI. Authorization Servers MUST accept this. The choice is to use user_code as the complete query string (eg https://example.com/device?wdjb-mjht) or specify a “code” parameter name (eg https://example.com/device?code=wdjb-mjht).

Recommending case-insensitive punctuation-ignoring alphabetic codes is good, but how does a user know this is the case for a particular code? Perhaps the advice needs to be to use a “fancy” input field with javascript to convert to uppercase as the user types and handle punctuation?

[§6.1] The example user code “WDJB-MJHT” doesn’t have “24^8 bits of entropy”, but “log2(24 ^ 8) = 36.7 bits of entropy”.

--
James Manger

On Mon, Feb 27, 2017 at 9:46 AM, <[email-masked]<mailto:[email-masked]>> wrote:
        Title           : OAuth 2.0 Device Flow for Browserless and Input Constrained Devices
        Filename        : draft-ietf-oauth-device-flow-04.txt

Abstract:
   This OAuth 2.0 authorization flow for browserless and input
   constrained devices, often referred to as the device flow, enables
   OAuth clients to request user authorization from devices that have an
   Internet connection, but don't have an easy input method (such as a
   smart TV, media console, picture frame, or printer), or lack a
   suitable browser for a more traditional OAuth flow.  This
   authorization flow instructs the user to perform the authorization
   request on a secondary device, such as a smartphone.  There is no
   requirement for communication between the constrained device and the
   user's secondary device.

https://tools.ietf.org/html/draft-ietf-oauth-device-flow-04

---

From: William Denniss <[email-masked]>
Date: Tue, 28 Feb 2017 16:39:50 -0800

Thanks for your review James!

On Tue, Feb 28, 2017 at 4:23 PM, Manger, James <
[email-masked]> wrote:

> *From:* Manger, James
> *Sent:* Tuesday, 28 February 2017 9:53 AM
> *To:* [email-masked]
> *Subject:* draft-ietf-oauth-device-flow: url with code
>
>
>
> The Device Flow provides a verification_uri and user_code, both of which
> have to be copied to a web browser on, say, a mobile phone. The main model
> in this draft is that the user copies the uri, then the resulting web page
> prompts for the code.
>

Correct. And note that there is a high probability that the user will make
errors, one reason why it's better for them to get the URI input first
(which may get browser auto-complete), before asking for the code.

> The draft also mentions other possibilities such as Bluetooth to do the
> “copying”. Transmitting a URI via Bluetooth, or NFC, or QR code, is quite
> common. In such cases it would be nicer to transmit the user_code as part
> of the URI.
>

I don't really see the benefit.

If you're doing some kind of out-of-band transmission (which is mentioned
as out of scope of the spec) there's no reason you can't simply transmit
both pieces of information.  We've done that before, and this is what we
do.  Having the data separate did not really alter the implementation of
this, and combining it wouldn't measurably make it simpler (but it would
make the spec more complex).

Also if the AS really wanted to, there's nothing to stop it including
whatever parameters it wanted in the verification URI today (which could
include the user code).

So I'd prefer to keep 1 protocol, designed for the browser model (which is
the only thing in-scope in the spec), that can potentially work with a wide
range of cases.

> Perhaps both modes could be supported by saying the user_code can be
> included as a query parameter on the verification_uri when it is more
> convenient for a device to transmit a single URI. Authorization Servers
> MUST accept this. The choice is to use user_code as the complete query
> string (eg https://example.com/device?wdjb-mjht) or specify a “code”
> parameter name (eg https://example.com/device?code=wdjb-mjht).
>

-1. I know for sure Google's AS will not comply with that MUST. As it is
there are some phishing concerns around this flow (documented in the spec),
and this change unfortunately makes the matter worse by allowing for
single-click phishing.

For example, we use the text today: "Enter the code displayed on your
device". And we display a picture picture of the device to help guide the
user as to the expected usage of this flow (this by itself isn't everything
– but they are important hints).

> Recommending case-insensitive punctuation-ignoring alphabetic codes is
> good, but how does a user know this is the case for a particular code?
> Perhaps the advice needs to be to use a “fancy” input field with javascript
> to convert to uppercase as the user types and handle punctuation?
>

I believe that's covered:

   The server should ignore any characters like punctuation that are not
   in the user-code character set.  Provided that the character set
   doesn't include characters of different case, the comparison should
   be case insensitive.

>
>
>
>
> [§6.1] The example user code “WDJB-MJHT” doesn’t have “24^8 bits of
> entropy”, but “log2(24 ^ 8) = 36.7 bits of entropy”.
>

Good point.

Best,
William

>
> --
>
> James Manger
>
>
>
>
>
> On Mon, Feb 27, 2017 at 9:46 AM, <[email-masked]> wrote:
>

---

From: "Manger, James" <[email-masked]>
Date: Wed, 1 Mar 2017 02:06:58 +0000

>> Transmitting a URI via Bluetooth, or NFC, or QR code, is quite common. In such cases it would be nicer to transmit the user_code as part of the URI.

> I don't really see the benefit.

If the device is always used with a pre-installed companion mobile app: no benefit.
If the device has ample screen size for "To register, visit <uri> and enter <code>": no benefit.
If the device can use NFC/BLE/QR-code/… to transmit a URI: benefit; can get verification_uri and user_code to a mobile browser without anything else (on the device or on the mobile).

Scenario: a device with no screen, just a few LEDs; the instructions say "to activate, tap the device with your mobile (after enabling NFC or bluetooth)".
User taps with mobile; browser launches; AS shows picture of device and asks user to confirm LEDs are flashing red/green/red/green… (on form with CSRF-protection); user click Yes; next device polling token request succeeds.

This scenario is harder without a standard way to combine verification_uri and user_code into a single URI.

> If you're doing some kind of out-of-band transmission (which is mentioned as out of scope of the spec) there's no reason you can't simply transmit both pieces of information.

My guess is that "transmitting both pieces of info" requires special-purpose code that understands those 2 pieces. Whereas browsing to a transmitted URI is generic.

>  We've done that before, and this is what we do.  Having the data separate did not really alter the implementation of this, and combining it wouldn't measurably make it simpler (but it would make the spec more complex).
>
> Also if the AS really wanted to, there's nothing to stop it including whatever parameters it wanted in the verification URI today (which could include the user code).

> So I'd prefer to keep 1 protocol, designed for the browser model (which is the only thing in-scope in the spec), that can potentially work with a wide range of cases.

It is still the browser model; it's just how the URI and code get to the browser.

 >> Perhaps both modes could be supported by saying the user_code can be included as a query parameter on the verification_uri when it is more convenient for a device to transmit a single URI. Authorization Servers MUST accept this. The choice is to use user_code as the complete query string (eg https://example.com/device?wdjb-mjht) or specify a “code” parameter name (eg https://example.com/device?code=wdjb-mjht).

> -1. I know for sure Google's AS will not comply with that MUST. As it is there are some phishing concerns around this flow (documented in the spec), and this change unfortunately makes the matter worse by allowing for single-click phishing.

I didn't mean to imply the AS had to *finish* the flow immediately when uri?code was accessed. An AS can still display anti-phishing measures requiring explicit user clicks to continue. The AS could still display a picture of the device.

I do concede that requiring a code to be manually entered is a specific phishing defence so any alternative should probably be specified separately.

> For example, we use the text today: "Enter the code displayed on your device". And we display a picture picture of the device to help guide the user as to the expected usage of this flow (this by itself isn't everything – but they are important hints).

>   The server should ignore …

I guess I read that as a suggestion for server-side code. But the user needs a hint at the client-side as they enter the code.
This is a minor detail. A web form could, for instance, say "case and punctuation are ignored" below the code input field.
  
--
James Manger

---

From: William Denniss <[email-masked]>
Date: Tue, 28 Feb 2017 18:47:56 -0800

On Tue, Feb 28, 2017 at 6:06 PM, Manger, James <[email-masked].
com> wrote:

> >> Transmitting a URI via Bluetooth, or NFC, or QR code, is quite common.
> In such cases it would be nicer to transmit the user_code as part of the
> URI.
>
> If the device can use NFC/BLE/QR-code/… to transmit a URI: benefit; can
> get verification_uri and user_code to a mobile browser without anything
> else (on the device or on the mobile).
>
> Scenario: a device with no screen, just a few LEDs; the instructions say
> "to activate, tap the device with your mobile (after enabling NFC or
> bluetooth)".
> User taps with mobile; browser launches; AS shows picture of device and
> asks user to confirm LEDs are flashing red/green/red/green… (on form with
> CSRF-protection); user click Yes; next device polling token request
> succeeds.
>

I don't see how this would be interoperable, how would the AS know about
the specifics of the device such as the color of the LEDs?  If you're
already relying on implementation specifics, like negotiating with the
client about the color of the LED, then you could also negotiate that the
code can be appended in any way that you both agree.  This is why I
suggested such advanced pairing would be out-of-scope.

I think a more plausible interop scenario would be that the URI and the
code are displayed as normal, but there's a step-up convenience option,
like QR code or NFC that combines the two. For users with a QR reader or
NFC they could use it, others could do it the old way.

> both pieces of information.
>
> My guess is that "transmitting both pieces of info" requires
> special-purpose code that understands those 2 pieces. Whereas browsing to a
> transmitted URI is generic.
>
> >  We've done that before, and this is what we do.  Having the data
> separate did not really alter the implementation of this, and combining it
> wouldn't measurably make it simpler (but it would make the spec more
> complex).
> >
> > So I'd prefer to keep 1 protocol, designed for the browser model (which
> is the only thing in-scope in the spec), that can potentially work with a
> wide range of cases.
>
> I didn't mean to imply the AS had to *finish* the flow immediately when
> uri?code was accessed. An AS can still display anti-phishing measures
> requiring explicit user clicks to continue. The AS could still display a
> picture of the device.
>
> I do concede that requiring a code to be manually entered is a specific
> phishing defence so any alternative should probably be specified separately
>

I know for sure that Google's AS will not implement this MUST. We've talked
about it in the past (including the unfinished pre-filled scenario you
outlined) and it was rejected due to increased phishing risk. I don't know
how others who've implemented early versions of this spec will act, but I
think introducing this MUST after so many years will harm interop.

I'm not necessarily saying that nobody should accept pre-filled codes
though, only that it was the direction my team went.

A MAY might be an option. E.g. the authorization server MAY accept the
authorization URI with an appended user code (appended in a standard way).
But that the client MUST still display the code in case the AS ignores the
param and requires it to be manually entered, and for verification purposes.

For servers who accept the pre-fill, I think the UX advice would be that
the user is still prompted to confirm the code visually.  Since the device
needs to display the code in all cases, even if only for confirmation
purposes, then that actually still works fine for an AS that decides to
require manual input.

That compromise could potentially work.

> I guess I read that as a suggestion for server-side code. But the user
> needs a hint at the client-side as they enter the code.
> This is a minor detail. A web form could, for instance, say "case and
> punctuation are ignored" below the code input field.
>

It wasn't meant to imply a server-side action, only that it's an
authorization server responsibility (which could be handled client side).
The text could be clarified if it's ambiguous.

William