Subject: Re: [OAUTH-WG] Fwd: issues with token age element - MAC token

From: Skylar Woodward <[email-masked]>
Date: Wed, 1 Jun 2011 09:15:39 +0200

Provider:  api.megaworld.com

Software Program: A universal binary iOS app called MegaWorld for iOS
Client ID:  mega_app

User:  Frankie in London
Username:  frankie_uk

Device A:  Frankie's iPhone
Device B:  Frankie's iPad

Now imagine MegaWorld for iOS installed on device A & B.  Client ID is the same across the two devices.

- Frankie uses device A to authorize his iPhone to allow MegaWorld for iOS to access his account (frankie_uk)
- Device A is issued MAC token with ID: 89ARC at UTC time 1306911549. Time on device A is 1306911444.
- Frankie uses device B to authorize his iPhone to allow MegaWorld for iOS to access his account (frankie_uk)
- Device B is issued MAC token with ID: 89ARC at UTC time 1306917830. Time on device B is 1275375611.

The provider, mega_app, does not issue multiple tokens for the same grant request (scope, client_id). This simplifies provider implementation but also helps enforce the correct user UI with respect to credential control at http://megaworld.com/my/apps - that is, the provider can't accurately know if frankie_uk has authorized one software instance twice on the same device, or multiple software instances once each (across multiple devices). Thus, the my/apps UI shows one authorization for "Megaworld for iOS" and thus one option to de-authorize this client_id (and thus all installed instances of the single software program with ID mega_app).

Regardless if age or timestamp is used, if the implementation for validating the time value is sequential (perhaps with some window of error) then one device will have all its OAuth requests rejected as soon as the other presents a request. If timestamps are used the one with the older clock (device B) is rejected. If age is used, the one with the highest value of time (in this case, the more correct client) will be rejected as age will be calculated to be smaller than device B with an incorrect clock.

If you also consider the case where device A and B have the same value for current time (UTC time, let's say) then age fails for device B after device A submits a request since device B thinks the credential is younger than device A. Timestamp does not fail in this case (because clocks are already sync'd).

Only when the timestamp is a unified standard like UTC can both device A and B both use token 89ARC. If client B has it's request rejected it can quickly check UTC from any reasonable source (including api.megaworld.com) to correct its clock. Even better, it can politely check the correct system time on a regular basis and cache the offset between UTC and device time. Though experience may show that many software developers don't currently do this clock correction, it is trivial to adopt as a best practice. (Many software developer also don't routinely review their software for security or stability vulnerabilities of any sort.) Certainly is nothing for the small percentage of well-written high-value clients such as Firefox, TweetDeck or any serious effort with even moderate distribution or engineering resources.

skylar

On Jun 1, 2011, at 8:36 AM, Eran Hammer-Lahav wrote:

> This is not true.
> 
> The age value has to be monotonically increasing, but not necessarily unique. Really, any counter will do. The reason why timestamp isn't any better than age or sequence is because ultimately, it is the server's memory restriction which determines the nonces storage size, not anything else (like a time limit).

---

From: Adam Barth <[email-masked]>
Date: Wed, 1 Jun 2011 00:24:57 -0700

Sounds like Eran's proposal will work fine for this scenario.
MegaWorld for iOS can just do what you suggest in the final paragraph,
which meets the new requirements for age.  I'm glad we're able to
address you use case.

Thanks,
Adam

---

From: Eran Hammer-Lahav <[email-masked]>
Date: Wed, 1 Jun 2011 00:33:13 -0700

> -----Original Message-----
> From: Skylar Woodward [mailto:[email-masked]]
> Sent: Wednesday, June 01, 2011 12:16 AM
> To: Eran Hammer-Lahav
> Cc: Adam Barth; OAuth WG
> Subject: Re: [OAUTH-WG] Fwd: issues with token age element - MAC token
> 
> Software Program: A universal binary iOS app called MegaWorld for iOS Client
> ID:  mega_app
> 
> User:  Frankie in London
> Username:  frankie_uk
> 

This is broken. You are using MAC for client authentication, but your client is a native application which should not have a secret...

> on device B is 1275375611.

When you say issued, you mean MAC credentials (access token) or client credentials?

EHL

> The provider, mega_app, does not issue multiple tokens for the same grant
> request (scope, client_id). This simplifies provider implementation but also
> helps enforce the correct user UI with respect to credential control at
> http://megaworld.com/my/apps - that is, the provider can't accurately know
> if frankie_uk has authorized one software instance twice on the same
> device, or multiple software instances once each (across multiple devices).
> Thus, the my/apps UI shows one authorization for "Megaworld for iOS" and
> thus one option to de-authorize this client_id (and thus all installed instances
> of the single software program with ID mega_app).
> 
> Regardless if age or timestamp is used, if the implementation for validating
> the time value is sequential (perhaps with some window of error) then one
> device will have all its OAuth requests rejected as soon as the other presents
> a request. If timestamps are used the one with the older clock (device B) is
> rejected. If age is used, the one with the highest value of time (in this case,
> the more correct client) will be rejected as age will be calculated to be smaller
> than device B with an incorrect clock.
> 
> If you also consider the case where device A and B have the same value for
> current time (UTC time, let's say) then age fails for device B after device A
> submits a request since device B thinks the credential is younger than device
> A. Timestamp does not fail in this case (because clocks are already sync'd).
> 
> Only when the timestamp is a unified standard like UTC can both device A
> and B both use token 89ARC. If client B has it's request rejected it can quickly
> check UTC from any reasonable source (including api.megaworld.com) to
> correct its clock. Even better, it can politely check the correct system time on
> a regular basis and cache the offset between UTC and device time. Though
> experience may show that many software developers don't currently do this
> clock correction, it is trivial to adopt as a best practice. (Many software
> developer also don't routinely review their software for security or stability
> vulnerabilities of any sort.) Certainly is nothing for the small percentage of
> well-written high-value clients such as Firefox, TweetDeck or any serious
> effort with even moderate distribution or engineering resources.
> 
> skylar
> 
> 
> > The age value has to be monotonically increasing, but not necessarily
> unique. Really, any counter will do. The reason why timestamp isn't any
> better than age or sequence is because ultimately, it is the server's memory
> restriction which determines the nonces storage size, not anything else (like
> a time limit).

---

From: Skylar Woodward <[email-masked]>
Date: Wed, 1 Jun 2011 09:35:24 +0200

Actually, monotonically increasing fails for this use case because even if clocks are sync'd, device A and B can submit requests sequentially in UTC time but could arrive in reverse order.

So monotonically increasing, with some tolerance or window of error would seem to be sufficient for allowing the server to expire nonces yet accounting for the complications of multiple devices presenting the same token. If providers were left to determine the window of error (which is really just a way of the provider controlling allocations for nonce storage) then it could accommodate for minor variances in device system time as before as well.

skylar

---

From: Skylar Woodward <[email-masked]>
Date: Wed, 1 Jun 2011 10:05:42 +0200

> This is broken. You are using MAC for client authentication, but your client is a native application which should not have a secret...

No, I had two use cases to discuss. One of access tokens being re-issued and the other of client credentials. Token re-issue seemed easier to explain because it is the more common case of device conflict. 

The issues with client credentials are minimized with the algorithm for nonce expiration that Adam suggested (sequential) which was not clear as a suggestion by the spec.  I could outline a problem with age for client credentials which use the "flagged as old" algorithm, but this seems less important now if we assume "sequential with a window of tolerance" as the algorithm for invalidation.

However, there are possible cases where two software instances use the same client credential (and where it's still possible to secure the secret). Most of those cases are ones where the software distribution is protected inside a controlled network.  A few examples (not common across OAuth, though some of these will be popular for providers like Kiva where its customers deploy proprietary software inside controlled intranets where secrets can be protected from the public even in "native" apps):

- Great State University makes an app for managing student grading. This app is distributed to all faculty iPhones using the Apple Enterprise Deployment system. GSU expects faculty not to share the installed software with non-faculty or to use jail-broken phones -- doing so is a violation of school code of ethics. GSU makes the case that the client credentials in the grading app are securable with reasonable deployment and legal protections in place. All installs of the app onto faculty iPhones use the same client credential. They use the client credential as an additional hurdle to protect against forged clients trying to authorize.

- Green Microlender makes an app for submitting loan data to Kiva that also interfaces with their local MIS system. This is a Visual Basic program installed on Windows PCs throughout field offices in southern Uganda which each on the organization's protected VLAN (or multiple protected LANs). This program is deployed by IT staff only onto these devices. They choose to use client credentials in this program as they feel comfortable in asserting that the client secrets are protected adequately by Green Microlender.

- MegaWorld Tracker deploys websites in France and the US.  They set up different instances of their website program in servers in France and the US. Each deployment is configured with the same MegaWorld OAuth client ID since it is the same program, but different locale settings to make the software render text in French or English, respectively. Since MegaWorld Tracker isn't a huge corp, they've haven't put in place measures to sync user's access tokens between the French servers and the US servers. This means a user that hits both the FR server and the US server will have to authenticate twice to megaworld.com (and thus access tokens issued to each server install). Since they also didn't bother to register two client IDs (mw_tracker instead of mw_tracker_us and mw_tracker_fr) they essentially have two installs using the same client credentials. It's a reasonable gray area.

I do admit these won't be en masse in the grand collective of all deployed OAuth v2 apps, but they are reasonable use cases, and for some organizations, very important use cases.

> When you say issued, you mean MAC credentials (access token) or client credentials?

these are access tokens

---

From: Torsten Lodderstedt <[email-masked]>
Date: Wed, 01 Jun 2011 10:11:31 +0200

Hi Mark,

Am 31.05.2011 22:58, schrieb Mark Mcgloin:
> Eran
>
> Here are some additional sections to add to the next draft under security
> considerations
>
> CSRF
> Cross-Site Request Forgery (CSRF) is a web-based attack whereby HTTP
> requests are transmitted from a user that the website trusts or has
> authenticated. CSRF attacks on OAuth approvals can allow an attacker to
> obtain authorization to OAuth Protected Resources without the consent of
> the User.
> The state parameter should be used to mitigate against CSRF attacks,
> particularly for login CSRF attacks. It is strongly RECOMMENDED that the
> client sends the state parameter with authorization requests to the
> authorization server. The authorization server will send it in the response
> when redirecting the user to back to the client which SHOULD then validate
> the state parameter matches on the response.

As far as I understand, the goal of the countermeasure is to bind the 
authz flow to a certain user agent (instance). So client must verify 
that the state parameter (or any other URL parameter?) matches some data 
found in the user agent itself before further processing the authz code.

Breno explained it as follows:
-----
- Client or user-agent generates a secret.
- The secret is stored in a location accessible only by the client or 
the user agent (i.e., protected by same-origin policy). E.g.: DOM 
variable (protected by javascript or other DOM-binding language's 
enforcement of SOP), HTTP cookie, HTML5 client-side storage, etc.
- The secret is attached to the state before a request is issued by the 
client
- When the response is received, before accepting the token or code, the 
client consults the user agent state and rejects the response altogether 
if the state does not match the user agent's stored value.
----

I would suggest to incorporate this into the decription:

It is strongly RECOMMENDED that the client sends the state parameter with authorization requests to the authorization server. _The state parameter MUST refer to a secret value retained at the user agent._ The authorization server will send the _state parameter_ in the response when redirecting the user to back to the client which _MUST_ then validate the state parameter_'s value against the secret value in the user agent_.

regards,
Torsten.

> Clickjacking
> Clickjacking is the process of tricking users into revealing confidential
> information or taking control of their computer while clicking on seemingly
> innocuous web pages. In more detail, a malicious site loads the target site
> in a transparent iframe overlaid on top of a set of dummy buttons which are
> carefully constructed to be placed directly under important buttons on the
> target site. When a user clicks a visible button, they are actually
> clicking a button (such as an "Authorize" button) on the hidden page.
> To prevent clickjacking (and phishing attacks), native applications SHOULD
> use external browsers instead of embedding browsers in an iFrame when
> requesting end-user authorization. For newer browsers, avoidance of iFrames
> can be enforced server side by using the X-FRAME-OPTION header. This header
> can have two values, deny and sameorigin, which will block any framing or
> framing by sites with a different origin, respectively. For older browsers,
> javascript framebusting techniques can be used but may not be effective in
> all browsers.
>
>
> Regards
> Mark
>
> _______________________________________________
> OAuth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/oauth

---

From: Eran Hammer-Lahav <[email-masked]>
Date: Wed, 1 Jun 2011 07:16:48 -0700

Then all these clients sharing the same credentials will require clock sync (not a problem for cell phones usually, but can be for other devices). But if you are implementing OAuth 2.0, the request including client authentication is made over TLS (as required) and so replay isn't much of a concern. If for some reason you are not using TLS alongside client authentication for obtaining an access token, this particular use case becomes out of scope.

EHL

> Sent: Wednesday, June 01, 2011 1:06 AM
> To: Eran Hammer-Lahav
> Cc: Adam Barth; OAuth WG
> >> Client
> > This is broken. You are using MAC for client authentication, but your client
> is a native application which should not have a secret...
> 
> No, I had two use cases to discuss. One of access tokens being re-issued and
> the other of client credentials. Token re-issue seemed easier to explain
> because it is the more common case of device conflict.
> 
> The issues with client credentials are minimized with the algorithm for nonce
> expiration that Adam suggested (sequential) which was not clear as a
> suggestion by the spec.  I could outline a problem with age for client
> credentials which use the "flagged as old" algorithm, but this seems less
> important now if we assume "sequential with a window of tolerance" as the
> algorithm for invalidation.
> 
> However, there are possible cases where two software instances use the
> same client credential (and where it's still possible to secure the secret).
> Most of those cases are ones where the software distribution is protected
> inside a controlled network.  A few examples (not common across OAuth,
> though some of these will be popular for providers like Kiva where its
> customers deploy proprietary software inside controlled intranets where
> secrets can be protected from the public even in "native" apps):
> 
> - Great State University makes an app for managing student grading. This app
> is distributed to all faculty iPhones using the Apple Enterprise Deployment
> system. GSU expects faculty not to share the installed software with non-
> faculty or to use jail-broken phones -- doing so is a violation of school code of
> ethics. GSU makes the case that the client credentials in the grading app are
> securable with reasonable deployment and legal protections in place. All
> installs of the app onto faculty iPhones use the same client credential. They
> use the client credential as an additional hurdle to protect against forged
> clients trying to authorize.
> 
> - Green Microlender makes an app for submitting loan data to Kiva that also
> interfaces with their local MIS system. This is a Visual Basic program installed
> on Windows PCs throughout field offices in southern Uganda which each on
> the organization's protected VLAN (or multiple protected LANs). This
> program is deployed by IT staff only onto these devices. They choose to use
> client credentials in this program as they feel comfortable in asserting that
> the client secrets are protected adequately by Green Microlender.
> 
> - MegaWorld Tracker deploys websites in France and the US.  They set up
> different instances of their website program in servers in France and the US.
> Each deployment is configured with the same MegaWorld OAuth client ID
> since it is the same program, but different locale settings to make the
> software render text in French or English, respectively. Since MegaWorld
> Tracker isn't a huge corp, they've haven't put in place measures to sync user's
> access tokens between the French servers and the US servers. This means a
> user that hits both the FR server and the US server will have to authenticate
> twice to megaworld.com (and thus access tokens issued to each server
> install). Since they also didn't bother to register two client IDs (mw_tracker
> instead of mw_tracker_us and mw_tracker_fr) they essentially have two
> installs using the same client credentials. It's a reasonable gray area.
> 
> I do admit these won't be en masse in the grand collective of all deployed
> OAuth v2 apps, but they are reasonable use cases, and for some
> organizations, very important use cases.
> 
> 
> >> - Frankie uses device A to authorize his iPhone to allow MegaWorld
> >> for iOS to access his account (frankie_uk)
> >> - Frankie uses device B to authorize his iPhone to allow MegaWorld
> >> for iOS to access his account (frankie_uk)
> >> The provider, mega_app, does not issue multiple tokens for the same
> >> grant request (scope, client_id). This simplifies provider
> >> implementation but also helps enforce the correct user UI with
> >> respect to credential control at http://megaworld.com/my/apps - that
> >> is, the provider can't accurately know if frankie_uk has authorized
> >> one software instance twice on the same device, or multiple software
> instances once each (across multiple devices).
> >> Thus, the my/apps UI shows one authorization for "Megaworld for iOS"
> >> and thus one option to de-authorize this client_id (and thus all
> >> installed instances of the single software program with ID mega_app).
> >>
> >> Regardless if age or timestamp is used, if the implementation for
> >> validating the time value is sequential (perhaps with some window of
> >> error) then one device will have all its OAuth requests rejected as
> >> soon as the other presents a request. If timestamps are used the one
> >> with the older clock (device B) is rejected. If age is used, the one
> >> with the highest value of time (in this case, the more correct
> >> client) will be rejected as age will be calculated to be smaller than device B
> with an incorrect clock.
> >>
> >> If you also consider the case where device A and B have the same
> >> value for current time (UTC time, let's say) then age fails for
> >> device B after device A submits a request since device B thinks the
> >> credential is younger than device A. Timestamp does not fail in this case
> (because clocks are already sync'd).
> >>
> >> Only when the timestamp is a unified standard like UTC can both
> >> device A and B both use token 89ARC. If client B has it's request
> >> rejected it can quickly check UTC from any reasonable source
> >> (including api.megaworld.com) to correct its clock. Even better, it
> >> can politely check the correct system time on a regular basis and
> >> cache the offset between UTC and device time. Though experience may
> >> show that many software developers don't currently do this clock
> >> correction, it is trivial to adopt as a best practice. (Many software
> >> developer also don't routinely review their software for security or
> >> stability vulnerabilities of any sort.) Certainly is nothing for the
> >> small percentage of well-written high-value clients such as Firefox,
> TweetDeck or any serious effort with even moderate distribution or
> engineering resources.
> >>
> >> skylar
> >>
> >>
> >> unique. Really, any counter will do. The reason why timestamp isn't
> >> any better than age or sequence is because ultimately, it is the
> >> server's memory restriction which determines the nonces storage size,
> >> not anything else (like a time limit).
> >

---

From: Mark Mcgloin <[email-masked]>
Date: Wed, 1 Jun 2011 19:28:33 +0100

Hi Torsten

It was implicit that the state parameter would be secret and not guessable
but that it probably worth spelling out, as you and Breno state. Here is a
modified version

CSRF
Cross-Site Request Forgery (CSRF) is a web-based attack whereby HTTP
requests are transmitted from a user that the website trusts or has
authenticated. CSRF attacks on OAuth approvals can allow an attacker to
obtain authorization to OAuth Protected Resources without the consent of
the User.
The state parameter should be used to mitigate against CSRF attacks,
particularly for login CSRF attacks. It is strongly RECOMMENDED that the
client sends the state parameter with authorization requests to the
authorization server. The state parameter MUST be non-guessable and MUST be
a secret only accessible to the client. The authorization server will send
it in the response when redirecting the user to back to the client which
MUST then validate the state parameter matches on the response.

Regards
Mark

Torsten Lodderstedt <[email-masked]> wrote on 01/06/2011 09:11:31:

> From:
>
> Torsten Lodderstedt <[email-masked]>
>
> To:
>
> Mark Mcgloin/Ireland/IBM@IBMIE
>
> Cc:
>
> [email-masked]
>
> Date:
>
> 01/06/2011 09:11
>
> Subject:
>
> Re: [OAUTH-WG] Draft 16 Security Considerations additions
>
>
> Hi Mark,
>
> It is strongly RECOMMENDED that the client sends the state parameter
> with authorization requests to the authorization server. _The state
> parameter MUST refer to a secret value retained at the user agent._
> The authorization server will send the _state parameter_ in the
> response when redirecting the user to back to the client which
> _MUST_ then validate the state parameter_'s value against the secret
> value in the user agent_.
>
>
> regards,
> Torsten.
>
>
>
>
>
> > Clickjacking

---

From: Mark Mcgloin <[email-masked]>
Date: Wed, 1 Jun 2011 20:21:45 +0100

Hi William

Agree it is a good definition but I am not sure we need to spell out more
details as we are trying to keep this section tight. Developers can look up
CSRF if they are unsure. However, I will add the example of how it can
happen

Cross-Site Request Forgery (CSRF) is a web-based attack whereby HTTP
requests are transmitted from a user that the website trusts or has
authenticated _(e.g., via HTTP redirects or HTML forms)_. CSRF attacks on
OAuth approvals can allow an attacker to obtain authorization to OAuth
Protected Resources without the consent of the User.

Regards
Mark

"William J. Mills" <[email-masked]> wrote on 01/06/2011 00:17:44:

> From:
>
> "William J. Mills" <[email-masked]>
>
> To:
>
> Mark Mcgloin/Ireland/IBM@IBMIE, "[email-masked]" <[email-masked]>
>
> Date:
>
> 01/06/2011 00:17
>
> Subject:
>
> http://tools.ietf.org/html/rfc6265#section-8.2 has good text on CSRF
> definition, which I think is clearer.  Perhaps that can be used to
> touch up your first paragraph?
>
> From: Mark Mcgloin <[email-masked]>
> To: [email-masked]
> Sent: Tuesday, May 31, 2011 1:58 PM
> Subject: [OAUTH-WG] Draft 16 Security Considerations additions
>
> Eran
>