Subject: [OAUTH-WG] Text for Native Applications

From: Chuck Mortimore <[email-masked]>
Date: Tue, 24 May 2011 17:30:05 -0700

One of my items from yesterday was to update the text related to native applications.   Primary goals were to:

 1.  remove the explicit preference for authorization_code grant type
 2.  provide a brief overview on means of initiating authorization requests and receiving callbacks
 3.  discuss the pros/cons of the different authorization requests and grant types

Here is suggested text.

-cmort

-----------------------------

9.  Native Applications

A native application is a client which is installed and executes on the end-user's device (i.e. desktop application, native mobile application).  Native applications require special consideration related to security, platform capabilities, and overall end-user experience.  The following are examples of how native applications may utilize OAuth:

   o  Initiate an Authorization Request using an external user-agent: The native application can capture the response from the authorization server by providing a redirection URI identifying a custom URI scheme (registered with the operating system to invoke the native application as handler), or by providing a redirection URI identifying a server-hosted resource under the native application's control, which in turn makes the response available to the native application (e.g. using the user-agent window title or other locations accessible from outside the user-agent).
   o  Initiate an Authorization Request using an embedded user-agent:  The native application obtains the response by directly communicating with the embedded  user-agent.  Techniques include monitoring state changes emitted during URL loading, accessing the user-agent's cookie jar, etc.

When choosing between launching an external user-agent and an embedding a user-agent, native application developers should consider the following:

   o  External user-agents may improve completion rate as the end-user may already have an active session with the authorization server removing the need to re-authenticate, and provide a familiar user-agent user experience.  The end-user may also rely on extensions or add-ons to assist with authentication (e.g. password managers or 2-factor device reader).
   o  Embedded user-agents may offer an improved end-user flow, as they remove the need to switch context and open new windows.
   o  Embedded user-agents pose a security challenge because end-users are authenticating in an unidentified window without access to the visual protections offered by many user-agents.  Embedded user-agents educate end-user to trust unidentified requests for authentication (making phishing attacks easier to execute).

When choosing between implicit and authorization code grant types, the following should be considered:

   o  Native applications that use the authorization code grant type flow SHOULD do so without client password credentials, due to their inability to keep those credentials confidential.
   o  Native applications that use the implicit grant type may offer optimized performance in some scenarios due to reduced network requests

---

From: [email-masked]
Date: Wed, 25 May 2011 05:30:21 +0000

Hi Chuck,

one of the advantages of the authz code grant type is refresh token support. I would suggest to mention this in the comparision with the implicit grant type.

regards,
Torsten.
Gesendet mit BlackBerry® Webmail von Telekom Deutschland  

-----Original Message-----
From: Chuck Mortimore <[email-masked]>
Sender: [email-masked]
Date: Tue, 24 May 2011 17:30:05 
To: [email-masked]<[email-masked]>
Subject: [OAUTH-WG] Text for Native Applications

_______________________________________________
OAuth mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/oauth

---

From: Marius Scurtescu <[email-masked]>
Date: Tue, 24 May 2011 22:45:49 -0700

On Tue, May 24, 2011 at 5:30 PM, Chuck Mortimore
<[email-masked]> wrote:
> remove the explicit preference for authorization_code grant type
> provide a brief overview on means of initiating authorization requests and
> receiving callbacks
> discuss the pros/cons of the different authorization requests and grant
> types
>
> Here is suggested text.
>
> -cmort
>
> A native application is a client which is installed and executes on the
> end-user's device (i.e. desktop application, native mobile application).
>  Native applications require special consideration related to security,
> platform capabilities, and overall end-user experience.  The following are
> examples of how native applications may utilize OAuth:
>
>    o  Initiate an Authorization Request using an external user-agent: The
> native application can capture the response from the authorization server by
> providing a redirection URI identifying a custom URI scheme (registered with
> the operating system to invoke the native application as handler), or by
> providing a redirection URI identifying a server-hosted resource under the
> native application's control, which in turn makes the response available to
> the native application (e.g. using the user-agent window title or other
> locations accessible from outside the user-agent).

There are other techniques that can be used with an external browser:
- monitor cookie jar
- copy-and-paste (manual)
- automatic copy to clipboard and native app monitors clipboard
- local web server (no need for special native app flow, regular web
server flow just works)
- browser extensions
- file:// scheme with local HTML file with JavaScript and
corresponding browser plugin (native apps can easily install a plugin)

>    o  Initiate an Authorization Request using an embedded user-agent:  The
> native application obtains the response by directly communicating with the
> embedded  user-agent.  Techniques include monitoring state changes emitted
> during URL loading, accessing the user-agent's cookie jar, etc.

Embedded browsers normally also allow the application to see all HTTP
headers, in which case there is no need to look at the cookie jar,
just monitor Set-Cookie headers.

Also, same as with external browsers, the page title can be monitored as well.

I am attaching a document I circulated before, it provides details for
most of these techniques.

That being said, not sure what is the optimal level of details in this
case. Maybe mentioning just a few techniques as Chuck did is good
enough.

Marius

---

From: Chuck Mortimore <[email-masked]>
Date: Tue, 31 May 2011 10:41:36 -0700

Updated in language I just sent out - thanks.

On that note, we currently return refresh_token using the implicit grant type under certain controlled circumstances.   Facebook in turn uses the implicit grant type, and simply issues long term access_tokens.

Are there any strong objections to adding optional support for referesh_token on the implicit grant along with security considerations?

-cmort

On 5/24/11 10:30 PM, "[email-masked]" <[email-masked]> wrote:

Hi Chuck,

regards,
Torsten.

---

From: Doug Tangren <[email-masked]>
Date: Tue, 31 May 2011 14:00:38 -0400

-Doug Tangren
http://lessis.me

On Tue, May 31, 2011 at 1:41 PM, Chuck Mortimore
<[email-masked]>wrote:

>  Updated in language I just sent out – thanks.
>
> On that note, we currently return refresh_token using the implicit grant
> type under certain controlled circumstances.   Facebook in turn uses the
> implicit grant type, and simply issues long term access_tokens.
>
> Are there any strong objections to adding optional support for
> referesh_token on the implicit grant along with security considerations?
>

I was under the impression that one should not issue a refresh_token in an
implicit grant flow because in order to make a refresh_token request call,
you'd need send client credentials including the clients secret which an
implicit client can not store securely.

I think there is still a usability issue with the implicit flow in general
where there is no way in the spec to obtain an access token without
re-asking the user for authorization a second time even if the user has
already authorized your client.

---

From: Brian Campbell <[email-masked]>
Date: Tue, 31 May 2011 13:06:09 -0600

> already authorized your client.

I don't think there is anything in the spec (correct me if I'm wrong) saying
that an AS couldn't "remember" a user's authorization for a given client
using implicit so as to avoid subsequent prompts for authorization?

---

From: Torsten Lodderstedt <[email-masked]>
Date: Tue, 31 May 2011 23:01:49 +0200

I think refresh token support in implicit grant is worth a discussion. 
The main difference to authz code from a security perspective is that 
the refresh token as long term credential could be disclosed via the 
user agent's URL history. In my perception, this fact and the assumption 
that user agent clients (the primary audience of this grant type) are 
not able to securely store referesh tokens are the reasons why the spec 
currently does not support it.

wrt Facebook's implementation: is this really inline with the spec's 
idea of access token duration?

regards,
Torsten.

Am 31.05.2011 19:41, schrieb Chuck Mortimore:
> Updated in language I just sent out -- thanks.
>
> On that note, we currently return refresh_token using the implicit 
> grant type under certain controlled circumstances.   Facebook in turn 
> uses the implicit grant type, and simply issues long term access_tokens.
>
>     one of the advantages of the authz code grant type is refresh
>     token support. I would suggest to mention this in the comparision
>     with the implicit grant type.
>
>     regards,
>     Torsten.
>     To: [email-masked]<oauth <[email-masked]%3Coauth>@ietf.org>

---

From: Torsten Lodderstedt <[email-masked]>
Date: Tue, 31 May 2011 23:08:36 +0200

the security considerations section does recommend to not automatically 
process repeated authorizations without validating the client's identity

The authorization server SHOULD NOT automatically, without active
    end-user interaction, process repeated authorization requests without
    authenticating the client or relying on other measures to ensure the
    repeated request comes from a valid client and not an impersonator.

BTW: I would suggest to rephrase the last part to "... comes from the 
same client as authorized by the original authorization request"

regards,
Torsten.

Am 31.05.2011 21:06, schrieb Brian Campbell:
>
>
> On Tue, May 31, 2011 at 12:00 PM, Doug Tangren <[email-masked] 
> <mailto:[email-masked]>> wrote:
>
>
>     I think there is still a usability issue with the implicit flow in
>     general where there is no way in the spec to obtain an access
>     token without re-asking the user for authorization a second time
>     even if the user has already authorized your client.
>
>
> I don't think there is anything in the spec (correct me if I'm wrong) 
> saying that an AS couldn't "remember" a user's authorization for a 
> given client using implicit so as to avoid subsequent prompts for 
> authorization?
>
>

---

From: Torsten Lodderstedt <[email-masked]>
Date: Tue, 31 May 2011 23:16:59 +0200

Am 31.05.2011 20:00, schrieb Doug Tangren:
> <[email-masked] <mailto:[email-masked]>> wrote:
>
>     grant type under certain controlled circumstances.   Facebook in
>     turn uses the implicit grant type, and simply issues long term
>     access_tokens.
>
> I was under the impression that one should not issue a refresh_token 
> in an implicit grant flow because in order to make a refresh_token 
> request call, you'd need send client credentials including the clients 
> secret which an implicit client can not store securely.

It is possible to obtain refresh tokens using the authz code grant type 
without client authentication. So why not do the same with implicit 
grant? As long as the user authorizes the issuance of such tokens I 
don't see any problem. The refresh token is a client instance secret 
associated with the grant authorized by the end user and is issued to 
the originator of the authz request only. The problem with native 
clients is the distribution of client secrets not their aibility to 
securely store a dynamically created instance-related secret.

regards,
Torsten.

> general where there is no way in the spec to obtain an access token 
> without re-asking the user for authorization a second time even if the 
> user has already authorized your client.

---

From: Dave Nelson <[email-masked]>
Date: Tue, 31 May 2011 17:17:07 -0400

This issue has likely been discussed "long ago", but I'd like to
potentially re-open the discussion.

>    o  Native applications that use the authorization code grant type flow
> SHOULD do so without client password credentials, due to their inability to
> keep those credentials confidential.

I understand that, in a strict sense, a software component running in
a non-embedded environment cannot be guaranteed to maintain the
confidentiality of credentials entrusted to it.  On the other hand, I
think this proscription may go too far.  All security is a matter of
providing sufficient counter-measures to identified attack vectors,
and I believe that native applications probably *can* keep secrets
well enough to resist the types of attacks they are likely to be
subject to in certain specified use cases.  Perhaps the "SHOULD"
wording leaves enough room for implementations with credential hiding
mechanisms that are deemed appropriate in a given use scenario to
include the use of a client password.  I think it would be more
accurate to say that native applications SHOULD NOT include the client
password in the authorization grant type flow, *unless* the design of
the application can provide a sufficient level of protection for said
password storage to meet the risks identified in association with the
deployment scenario.

Thoughts?

Regards,

Dave

David B. Nelson
Sr. Software Architect
Elbrys Networks, Inc.
www.elbrys.com
+1.603.570.2636

---

From: Brian Eaton <[email-masked]>
Date: Tue, 31 May 2011 17:37:22 -0700

> referesh_token on the implicit grant along with security considerations?

Is that really necessary?  Why?

The justification of reduced network round trips seems bogus to me.
We're talking about clients that just loaded up an entire web page,
asked the user to login, picked up a redirect, and are about to make
at least one and possibly several other API calls.

I'd prefer to keep the spec simple and consistent.  We can add all
kinds of options and maybes to the language, but long-term it will
just hurt interop.  I'd rather settle on protocol flows that make
sense.

One risk that comes up with returning refresh tokens with the implicit
grant type involves recovering from compromise of client web servers.
That's not strictly relevant to the current distinction (we're talking
about installed apps, different threat model), but it might be worth
thinking about anyway.

Consider what happens when a client web server is compromised and the
client secret and refresh tokens are stolen.
- the attacker can use the tokens until the compromise is discovered.
- the client secret is then changed
- the stolen refresh tokens then become useless

Now, *if* the implicit grant type returns refresh token, that story
changes.  Even if the client secret is changed, the attacker can keep
using the refresh tokens!  They do it by passing them to the victim
client again, through the implicit grant flow.  The victim client will
then link the refresh token to the attacker's account.

---

From: Doug Tangren <[email-masked]>
Date: Tue, 31 May 2011 22:12:01 -0400

> using the refresh tokens!

I think this is exactly the point! It only makes sense for the auth code
flow where client credentials are supplied in the refresh token request. The
idea behind not issuing a refresh token to a client that can't store
confidential client credentials is there that is no protection against a
compromised refresh token. A refresh token request requires no redirection
and no interaction with a user so if I can grab it, I've got an endless all
access pass to your users' data until they deny your app access to their
data.

I may be a little misinformed when I talk about the implicit flow with
respect to a native client. I was mainly talking about its usage with
respect to browser-based client.

I wasn't aware about the auth code flows without secrets until the recent
suggested flows for native clients included the auth code flow with out a
secret.

There seem to be many recent changes that muddied the original security
considerations behind parameter and credentials requirements for the auth
and implicit flows. Now there is auth code flow server (client secret
required)/auth code flow for native apps (client secret optional) and
implicit flow for browser clients (no refresh token)/implicit flow for
native apps (optional refresh token?).

It feels like there should be a well-defined or at least more
narrowly-scoped flow for each intended usage instead of saying various
clients can use the same flow but in various different ways. This makes it
easy for developers to pick an choose which parameters they want to supply
but difficult for server providers to validate requests.

All that said, I do agree there is a user experience issue with the implicit
flow. From a user's perspective if feels annoying to be asked the same
question multiple times when the answer is always the same. I think I heard
mention of facebook using tokens that don't expire. From their
documentation, it sounds like they did the right thing. They don't do this
by default but provide it as an option that the user has to authorize.

"If your app needs an access token with an infinite expiry time (perhaps to
take actions on the user's behalf after they are not using your app), you
can request the *offline_access *permission."

If I read that right, that says the user has to opt into the access_token
not expiring. I believe this may be the smarted solution for now because it
uses the scope parameter to gain this additional access which is using the
actual protocol parameters as intended instead of hacking around them.

---

From: Kris Selden <[email-masked]>
Date: Tue, 31 May 2011 22:39:26 -0700

Why can't you just revoke the refresh token for a client when you change the client secret?

Is it not easier to revoke a token than it is to rotate the client secret (which is usually configured or embedded in the client whereas the token is issued)?

---

From: Brian Eaton <[email-masked]>
Date: Tue, 31 May 2011 23:05:11 -0700

> Is it not easier to revoke a token than it is to rotate the client secret (which is usually configured or embedded in the client whereas the token is issued)?

As I noted in my original e-mail on this thread, I was talking
specifically about the web server flow.

This is one area where the security considerations for installed
applications are different than for web servers.

---

From: Chuck Mortimore <[email-masked]>
Date: Tue, 31 May 2011 23:32:04 -0700

The distinction is that the client_secret tends to be a global secret, and there is little ability to protect this type of secret in many common means of application distribution.

For example, a iOS app that is shipped through iTunes certainly has access to reasonably secure storage via KeyChain for secrets issued to the application at runtime, such as the referesh_token, but it can't do a good job of protecting the client_secret, since this must be embeded in the binary that is distributed to everyone.

-cmort

On 5/31/11 2:17 PM, "Dave Nelson" <[email-masked]> wrote:

Thoughts?

Regards,

Dave

David B. Nelson
Sr. Software Architect
Elbrys Networks, Inc.
www.elbrys.com
+1.603.570.2636

---

From: Doug Tangren <[email-masked]>
Date: Wed, 1 Jun 2011 02:32:33 -0400

-Doug Tangren
http://lessis.me

> Why can't you just revoke the refresh token for a client when you change
This makes sense for a server implementation for added precaution but in
practice, most clients dont change client secrets often.

> Is it not easier to revoke a token than it is to rotate the client secret
> (which is usually configured or embedded in the client whereas the token is
> issued)?
>
>
Yes, providing a user means to revoke a token or to break a "connection" is
a defacto feature of most server implementations. However, most users will
accept the authorization for an app and forget about it.

---

From: Chuck Mortimore <[email-masked]>
Date: Tue, 31 May 2011 23:41:40 -0700

It's not entirely necessary; I'm just having a tough time figuring out any practical difference between the implicit grant flow, and the webserver flow with no credentials.   In general I agree with your points, but I think we have a similar, perhaps worse, scenario with relaxing the need for credentials on the web server flow.  In terms of your example, wouldn't basic XSRF protection in the state param protect?

-cmort

On 5/31/11 5:37 PM, "Brian Eaton" <[email-masked]> wrote:

---

From: Doug Tangren <[email-masked]>
Date: Wed, 1 Jun 2011 02:44:24 -0400

-Doug Tangren
http://lessis.me

For example, a iOS app that is shipped through iTunes certainly has access
> to reasonably secure storage via KeyChain for secrets issued to the
> application at runtime, such as the referesh_token, but it can’t do a good
> job of protecting the client_secret, since this must be embeded in the
> binary that is distributed to everyone.
>

Neither can anything that runs in you browser [1]

[1]:
https://github.com/cezarsa/silver_bird/commit/6c0c0b439d49f716ba5ea8ae2e13d15f2096c6fa

---

From: Kris Selden <[email-masked]>
Date: Tue, 31 May 2011 23:45:56 -0700

I would suspect that many users are overwhelmed when authorizing many fine grained scopes and don't fully understand the risks.  Many popular sites ask for offline access straight away upon connecting to Facebook (Foursquare, Quora, Instagram, etc).  This offline access token, has a higher chance of being exposed, like if you use the cookie: true option in the Facebook JS SDK (which Foursquare does), which sets a Javascript accessible non secure cookie on your domain which now means that if Foursquare makes a non secure http request to foursquare.com a non expiring bearer token will go out in plaintext.  Foursquare is https only but many sites that use the JS SDK aren't.

The biggest difference between a refresh token and a non-expiring access token is that the refresh token needs to be verified by the authorization server only whereas the access token needs to be verified by the resource servers.

-------

Here is the rationale in Scalable OAuth Extension (http://wiki.oauth.net/w/page/12238549/ScalableOAuth#RationaleforRenewableAccessTokensSessions) which was a predecessor to OAuth WRAP and OAuth 2:

Rationale for Renewable Access Tokens (Sessions)

Many Service Providers have the concept of a Session credential with a finite lifetime. Consumers authenticate with the Service Provider's Authentication Service to obtain a Session credential to access the Service Provider's protected resources. When the Session credential expires, the consumer is able to obtain a new Session credential by re-authenticating with the Authentication service. The primary benefit to this architecture is that Session credentials do not need to be revocable if they expire quickly, and that protected resources can be returned without a database lookup to verify that the consumer is still authorized.

Rationale for Auth Session (aka Refresh Secret)

Service Providers often run their Authentication Service separately from other protected resources. The Authentication Service is usually strictly monitored and controlled, while other Protected Resources may be running relatively new and unproven code.

In the event that a Protected Resource is compromised (the SP gets hacked), it is desirable to prevent the intruder from being able to continue to compromise the system after the vulnerability has been fixed. Issuing credentials with a finite lifetime limits the duration that the intruder can continue to use compromised credentials. Issuing a credential to a Consumer that is not known by the Protected Resource but is known by the Authentication Service can enable an Service Provider to revoke access to an intruder without requiring consumers to be reauthorized.

------

Another related issue with Native Apps like iPhone Apps that can't be shipped with a client secret is the end user's expectation to stay "logged in."  

On May 31, 2011, at 7:12 PM, Doug Tangren wrote:
> 
> "offline_access permission."
> 
> If I read that right, that says the user has to opt into the access_token not expiring. I believe this may be the smarted solution for now because it uses the scope parameter to gain this additional access which is using the actual protocol parameters as intended instead of hacking around them.

---

From: Kris Selden <[email-masked]>
Date: Tue, 31 May 2011 23:47:17 -0700

Yes, it is important to remember that when you make allowances for one flow you affect other flows, I understand that.  I understand that if in the implicit flow you return a refresh token, you then allow other flows to use authorization server endpoint to refresh the token without a client secret.

If a provider chooses to do that though, in the attack you described, they could still revoke the refresh token to stop the abuse when it is discovered, and that is still easier in my opinion than rotating a client secret but yes, allowing that does make the client secret pointless for refreshing tokens.

Like the client secret though, the refresh token is only exchanged with the authorization server and only over https.

I think the fact that the refresh token is only exchanged with the authorization server and not the resource servers, still makes it useful to apps that can't be shipped with a client secret.  I'm not a fan of the implicit flow and JS clients but would like to be able to use the other flows with native apps that can't be authenticated (like an iPhone app).  So it would be nice if client authentication was not required to refresh a token.

---

From: Brian Eaton <[email-masked]>
Date: Tue, 31 May 2011 23:56:50 -0700

On Tue, May 31, 2011 at 11:41 PM, Chuck Mortimore
<[email-masked]> wrote:
> It’s not entirely necessary; I’m just having a tough time figuring out any
> practical difference between the implicit grant flow, and the webserver flow
> with no credentials.   In general I agree with your points, but I think we
> have a similar, perhaps worse, scenario with relaxing the need for
> credentials on the web server flow.

No doubt. =)  I think it's unfortunate that the spec was changed to
make the client credentials optional for the web server flow.  As you
say, it's a security problem for web apps.  We are treating the client
secret as mandatory in our deployments, and basically everyone who
deploys the web server flow should do the same.  It's a shame the spec
is so vague on this point.

The root cause of the spec ambiguity was disagreement over how to
handle secrets for installed applications.  I can think of three paths
forward.

- split out "installed app flow" from "web server flow".  Use a new
grant type.  (DON'T switch installed apps to use the "implicit" grant
type.  That doesn't work either, because it doesn't return a
long-lived credential.  DON'T have the implicit grant type return a
refresh token directly, either, since that causes serious security
problems for real web apps that can keep client secrets.)

- make the client secret mandatory, but tell people who are offended
by client secrets in installed apps to use the string "notasecret" for
all installed apps.

- ignore the problem and leave the spec vague and insecure.

> In terms of your example, wouldn’t basic XSRF protection in the state param protect?

Nope.  Assume the following scenario:
- bad guy has stolen refresh token
- client web server has detected attack and changed their client secret
- bad guy wants to find a way to keep using the refresh token

If refresh tokens are returned without client authentication, the bad
guy can do it as follows:
- visit client.  log in as account badguy1234.
- client redirects to authorization server, including state=1234
- bad guy ignores redirect to authorization server, visits client
callback server with refresh_token=stolen&state=1234
- client picks up stolen refresh token and associates it with badguy1234.
- whenever badguy1234 visits the client web site, he can see data from
the stolen refresh token.

Cheers,
Brian