Subject: [OAUTH-WG] Indicating origin of OAuth credentials to combat login CSRF

From: "Manger, James H" <[email-masked]>
Date: Fri, 25 Feb 2011 11:08:33 +1100

Q. Should an OAuth client app list the authorization server in the Origin header of requests to resource servers?

In OAuth (delegation) flows a server dynamically issues credentials (such as a bearer token) to a client app to use in subsequent HTTP requests to other servers. To combat login cross-site request forgery (CSRF) attacks [1] (where an attacker's server issues the attacker's credentials to a client app to use on behalf of a victim at a legitimate server) the client app needs to indicate where the credentials came from. The Origin header [2] looks like the right place to indicate this.

[For the OAuth list: The Origin HTTP request header "indicates the origin(s) that caused the user agent to issue the request" [http://tools.ietf.org/html/draft-ietf-websec-origin-00#section-6.2].]

[For the WebSec list: An OAuth credential from an authorization server is a bit like a cookie, but not restricted to the same origin.]

Example:

  Client to (malicious) authorization server: ->

    POST /token HTTP/1.1

    Host: login.example.com

    ...

  <-

    HTTP/1.1 200 OK

    ...

    { "access_token": "SlAV32hkKG", ...}

  Client to resource server: ->

    POST /uploadData HTTP/1.1

    Host: api.exampledata.com

    Authorization: BEARER SlAV32hkKG

    Origin: https://login.example.com

    ...

There can be other servers that contribute to a client app making a request. For instance, one server can redirect to another. A Origin request header can list multiple origins. The server will not be able to distinguish which origin issued OAuth credentials from which issued a redirect etc. That might not matter if a server has to trust all the values listed in the Origin header.

Q. Is it the group's expectation that servers checking the Origin header will require all the listed origins to be trusted?

[1] Robust Defenses for Cross Site Request Forgery, http://www.adambarth.com/papers/2008/barth-jackson-mitchell-b.pdf

[2] The Web Origin Concept, http://tools.ietf.org/html/draft-ietf-websec-origin

[3] Principles of the Same Origin Policy, http://tools.ietf.org/html/draft-abarth-principles-of-origin

--

James Manger

---

From: Francisco Corella <[email-masked]>
Date: Fri, 25 Feb 2011 15:42:00 -0800 (PST)

Hi James,

You raise an interesting point.  I hadn't thought about the
threat of Login CSRF.

> Q. Should an OAuth client app list the authorization server
> in the Origin header of requests to resource servers?
> 
> In OAuth (delegation) flows a server dynamically issues
> credentials (such as a bearer token) to a client app to use
> in subsequent HTTP requests to other servers. To combat
> login cross-site request forgery (CSRF) attacks [1] (where
> an attacker‚Äôs server issues the attacker‚Äôs credentials to a
> client app ...

But how will the client app get the "credentials" (bearer token)
from the wrong authorization server?

Even though the particular attack you describe may not work,
OAuth is wide open to Login CSRF in a different way.  An
attacker can legitimately obtain an authorization code, and
then cause the victim's browser to submit it to the client
application, thus logging the victim in to the client
application as the attacker (in a social login scenario such
as "log in with Facebook").  I bet all applications that use
OAuth to delegate authentication (to Facebook, Twitter,
Google, LinkedIn, Yahoo, etc.) are vulnerable to this now.

One solution I would propose is to have the client set a
pre-session cookie in the user's browser before the first
redirection and include the value of the cookie in the local
state parameter that it sends to the authorization server.
The authorization server later returns the local state
together with the authorization code, and the browser adds
the cookie, so the client can prevent the attack by checking
that the value of the cookie agrees with the value it
included in the local state.

Francisco

---

From: Brian Eaton <[email-masked]>
Date: Fri, 25 Feb 2011 16:36:10 -0800

I don't think the advice from the OAuth 1.0a spec is wrong:

http://oauth.net/core/1.0a/#anchor38

"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. Service Providers SHOULD strongly consider best
practices in CSRF prevention at all OAuth endpoints.

CSRF attacks on OAuth callback URLs hosted by Consumers are also
possible. Consumers should prevent CSRF attacks on OAuth callback URLs
by verifying that the User at the Consumer site intended to complete
the OAuth negotiation with the Service Provider."

This is the purpose of the "state" parameter during the approval flows.

Cheers,
Brian

On Fri, Feb 25, 2011 at 3:42 PM, Francisco Corella <[email-masked]> wrote:
> _______________________________________________
> OAuth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/oauth
>

---

From: Francisco Corella <[email-masked]>
Date: Fri, 25 Feb 2011 17:54:39 -0800 (PST)

There is nothing wrong with telling people that they should prevent CSRF attacks :-)

But there is no explicit state parameter in OAuth 1.0a.  Do you think that implementors of 1.0a, just by reading section 11.14, are aware of the danger of Login CSRF and can figure out how to prevent it, using a pre-session cookie and implementing a state parameter that is not even mentioned in the specification?

Francisco

--- On Sat, 2/26/11, Brian Eaton <[email-masked]> wrote:

From: Brian Eaton <[email-masked]>
Subject: Re: [OAUTH-WG] Indicating origin of OAuth credentials to combat login CSRF
To: [email-masked]
Cc: "OAuth Mailing List" <[email-masked]>, "[email-masked]" <[email-masked]>, "James HManger" <[email-masked]>, "Karen P. Lewison" <[email-masked]>
Date: Saturday, February 26, 2011, 12:36 AM

Cheers,
Brian

---

From: Torsten Lodderstedt <[email-masked]>
Date: Sat, 26 Feb 2011 13:27:03 +0100

Hi James,

I would expect the token to carry information about its issuer. Would 
this be sufficient in order to detect CSRF?

regards,
Torsten.

Am 25.02.2011 01:08, schrieb Manger, James H:
>
> Q. Should an OAuth client app list the authorization server in the 
> Origin header of requests to resource servers?
>
> In OAuth (delegation) flows a server dynamically issues credentials 
> (such as a bearer token) to a client app to use in subsequent HTTP 
> requests to other servers. To combat login cross-site request forgery 
> (CSRF) attacks [1] (where an attacker's server issues the attacker's 
> credentials to a client app to use on behalf of a victim at a 
> legitimate server) the client app needs to indicate where the 
> credentials came from. The Origin header [2] looks like the right 
> place to indicate this.
>
> [For the OAuth list: The Origin HTTP request header "indicates the 
> origin(s) that caused the user agent to issue the request" 
> [http://tools.ietf.org/html/draft-ietf-websec-origin-00#section-6.2].]
>
> [For the WebSec list: An OAuth credential from an authorization server 
> is a bit like a cookie, but not restricted to the same origin.]
>
> Example:
>
> There can be other servers that contribute to a client app making a 
> request. For instance, one server can redirect to another. A Origin 
> request header can list multiple origins. The server will not be able 
> to distinguish which origin issued OAuth credentials from which issued 
> a redirect etc. That might not matter if a server has to trust all the 
> values listed in the Origin header.
>
> Q. Is it the group's expectation that servers checking the Origin 
> header will require all the listed origins to be trusted?
>
> [1] Robust Defenses for Cross Site Request Forgery, 
> http://www.adambarth.com/papers/2008/barth-jackson-mitchell-b.pdf
>
> [2] The Web Origin Concept, 
> http://tools.ietf.org/html/draft-ietf-websec-origin
>
> [3] Principles of the Same Origin Policy, 
> http://tools.ietf.org/html/draft-abarth-principles-of-origin
>
> --
>
> James Manger
>
>

---

From: "Manger, James H" <[email-masked]>
Date: Mon, 28 Feb 2011 09:40:49 +1100

Torsten Lodderstedt said: "I would expect the token to carry information about its issuer. Would this be sufficient in order to detect CSRF?"

No.

A Login CSRF attack involves a legitimate token (listing the legitimate issuer) that an attacker received being given to a victim client. The client gets a legitimate token - but they got it from the wrong party so they cannot be sure it was a token meant for them.

If the client tells the resource server where they got the token from then the resource server can confirm that there wasn't an attacker between the legitimate authorization server and client.

--

James Manger

Example:

    POST /token HTTP/1.1

    Host: login.example.com

    ...

  <-

    HTTP/1.1 200 OK

    ...

    ...

--

James Manger

---

From: "Manger, James H" <[email-masked]>
Date: Mon, 28 Feb 2011 14:27:25 +1100

Hi Francisco,

>> an attacker’s server issues the attacker’s credentials to a

> from the wrong authorization server?

A client app hardwired to use a specific single service cannot get a token from the wrong server. If the client app additionally never follows redirects or any other instructions from the server will not send the token to another service. Such an app is safe from login CSRF attacks, but hardly needs a interoperable web spec.

A client app that goes to whichever service a user points it at could get a token from any authorization server. For instance, a photo framing app that asks for the URL of your online photo store.

A client that follows HTTP redirects (or Link: header or any other variety of hypertext) might get directed to an 2nd service while still using the token from the 1st service.

I don’t see any way for a client to know the boundaries of an OAuth2 service – other than preconfigured service-specific knowledge. OAuth2 draft 10 said clients “MUST NOT make authenticated requests with an access token to unfamiliar resource servers”. Clients were assumed to be “familiar” with every server they contacted – the antithesis of web architecture. Later drafts don’t even have that language (it probably got lost in the doc split). I have previously argued for a ‘sites’ field in a token response to indicate where the token can be used. A client would still need to use the “Origin” header as protection against a malicious ‘sites’ value. [ http://www.ietf.org/mail-archive/web/oauth/current/msg02587.html Spec text for “sites” field]

--

James Manger

---

From: Francisco Corella <[email-masked]>
Date: Mon, 28 Feb 2011 10:22:32 -0800 (PST)

Hi James,

> A client that follows HTTP redirects (or Link: header or any
> other variety of hypertext) might get directed to an 2nd
> service while still using the token from the 1st service.

But why would a legitimate authorization server redirect the
client to an attacker's server?

Francisco

---

From: "Manger, James H" <[email-masked]>
Date: Tue, 1 Mar 2011 11:43:17 +1100

Francisco,

> client to an attacker's server?

It can happen the other way around. The 1st service acts maliciously, forwarding a token that was actually obtained from the 2nd service. The client then uses that token to make requests to the 2nd service - because it thinks it is part of the 1st service.

The core issue is that a client gets a opaque token from one service and will use it to access other resources. The token is opaque to the client:

1.       The client cannot check that the token was originally issued by this service (as opposed to this service forwarding a token from elsewhere);

2.       The client cannot check that the token was meant for itself (as opposed to being forwarded from another client);

3.       The client isn't told by the token issuer where it should & shouldn't be used (ie the boundary of the services);

4.       The client isn't told by a resource server which sources of tokens are legitimate.

One way to avoid some of these issues is to hardwire clients to a specific service - which is very limiting.

Another way is to have a standard token format - which is limiting, and a big burden on clients.

A better way is to accept points 1 & 2; address 3 by listing resource sites in token responses; and address 4 obliquely by listing the authorization server in the "Origin" HTTP request header. Then it doesn't matter if a client unwittingly connects with an attacker's service (just as it shouldn't matter to a legitimate web site if their web browser clients unwittingly visit malicious or compromised web sites).

--

James Manger

---

From: Francisco Corella <[email-masked]>
Date: Mon, 28 Feb 2011 21:16:49 -0800 (PST)

Hi James,

I think I got it now.  Thanks for explaining it so patiently.

The attack is only possible if there are multiple independent authorization servers that don't trust each other.  But the OAuth specification talks about multiple resource servers but only one authorization server.  I think there is an implicit assumption that the multiple resource servers will only accept tokens from the one authorization server.  By far the most widespread deployment of OAuth is for social login, as in "log in with Facebook".  In that case the authorization server is a Facebook endpoint, the resource servers are Facebook endpoints, and the attack is not possible.

Francisco

--- On Tue, 3/1/11, Manger, James H <[email-masked]> wrote:

From: Manger, James H <[email-masked]>
Subject: RE: [OAUTH-WG] Indicating origin of OAuth credentials to combat login CSRF
To: "[email-masked]" <[email-masked]>, "OAuth Mailing List" <[email-masked]>
Cc: "Karen P. Lewison" <[email-masked]>
Date: Tuesday, March 1, 2011, 12:43 AM

Francisco, 

> client to an attacker's server?

   
It can happen the other way around. The 1st service acts maliciously, forwarding a token that was actually obtained from the 2nd service.
 The client then uses that token to make requests to the 2nd service – because it thinks it is part of the 1st service. 
   
The core issue is that a client gets a opaque token from one service and will use it to access other resources. The token is opaque to the client: 
1.      
The client cannot check that the token was originally issued by this service (as opposed to this service forwarding a token from elsewhere); 
2.      
The client cannot check that the token was meant for itself (as opposed to being forwarded from another client); 
3.      
The client isn’t told by the token issuer where it should & shouldn’t be used (ie the boundary of the services); 
4.      
The client isn’t told by a resource server which sources of tokens are legitimate. 
   
One way to avoid some of these issues is to hardwire clients to a specific service – which is very limiting. 
Another way is to have a standard token format – which is limiting, and a big burden on clients. 
A better way is to accept points 1 & 2; address 3 by listing resource sites in token responses; and address 4 obliquely by listing the authorization server
 in the “Origin” HTTP request header. Then it doesn’t matter if a client unwittingly connects with an attacker’s service (just as it shouldn’t matter to a legitimate web site if their web browser clients unwittingly visit malicious or compromised web sites). 
   
-- 
James Manger

---

From: "Manger, James H" <[email-masked]>
Date: Tue, 1 Mar 2011 17:59:06 +1100

> The attack is only possible if there are multiple independent authorization servers that don't trust each other.

And there are. Facebook, Twitter, Photos-are-us, Xyz… can operate authorization servers; they are all independent; and don’t particularly trust each other. The attack doesn’t require a single resource server to trust all these independent authorization servers.

> By far the most widespread deployment of OAuth is for social login, as in "log in with Facebook".  In that case the authorization server is a Facebook endpoint, the resource servers are Facebook endpoints, and the attack is not possible

You are probably right that this attack is not possible against a client app offering a “login with facebook” button. Such a client is hardwired to work with a single service – which is one (very limiting) way to avoid these attacks.

A client accepting login from any social network (even ones the client hasn’t heard of) could be susceptible this attack. The “other” social network returns a token that it actually got from Facebook and gets the client app to use it at Facebook.

--

James Manger

From: Francisco Corella [mailto:[email-masked]]
Sent: Tuesday, 1 March 2011 4:17 PM
To: OAuth Mailing List; Manger, James H
Cc: Karen P. Lewison
Subject: RE: [OAUTH-WG] Indicating origin of OAuth credentials to combat login CSRF

Hi James,

Francisco

Francisco,

> client to an attacker's server?

It can happen the other way around. The 1st service acts maliciously, forwarding a token that was actually obtained from the 2nd service. The client then uses that token to make requests to the 2nd service – because it thinks it is part of the 1st service.

3.       The client isn’t told by the token issuer where it should & shouldn’t be used (ie the boundary of the services);

4.       The client isn’t told by a resource server which sources of tokens are legitimate.

A better way is to accept points 1 & 2; address 3 by listing resource sites in token responses; and address 4 obliquely by listing the authorization server in the “Origin” HTTP request header. Then it doesn’t matter if a client unwittingly connects with an attacker’s service (just as it shouldn’t matter to a legitimate web site if their web browser clients unwittingly visit malicious or compromised web sites).

--

James Manger