Subject: [websec] 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 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

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:
>
> 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
>
>
> _______________________________________________
> OAuth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/oauth
>

---

From: Adam Barth <[email-masked]>
Date: Fri, 25 Feb 2011 23:09:39 -0800

> header of requests to resource servers?

They are allowed to, but are not required to, by the Origin header
specification.  Whether they should or not is a question for the OAuth
working group to decide.

Adam

> 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:
>
>
>
>     …
>     …
>     { "access_token": "SlAV32hkKG", …}
>
>
>
>     …
> 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
>
>
>
> websec mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/websec
>
>

---

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

Hi James,

Francisco

---

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

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" 
> [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?
>

---

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

> specification.  Whether they should or not is a question for the OAuth

That is true, Adam, but I was hoping for a bit more advice from the group knowing most about "Origin" and cross-site requests about the need to indicate the server that dynamically provided an opaque value that the client is putting in the Authorization header of subsequent cross-origin requests.

Once specific question for websec is:
What semantics are associated with the *order* of origins in an "Origin" HTTP request header value?

The Origin spec implies (but doesn't explain) that there is some meaning to the order: a duplicate origin is omitted if it would be next to the same value (but included if there are intervening origins); and a site returning a redirect is appended to existing origins.

CORS seems to ignore the order of origins for non-preflight requests [http://www.w3.org/TR/cors/#resource-requests section 5.1 step 2].
CORS seems to imply a preflight request can only have a single origin in its "Origin" header [section 5.2 step 2]. That might not work well if OAuth says the authorization server shall be indicated in the "Origin" header as well.

Perhaps it would be better for the Origin header to be specified as a *set* of origins, not a list. That is, state that order doesn't matter (and no duplicates are allowed). Would that hinder any uses of Origin?

I suspect open redirectors are the problem. After a redirect, the origin of the original request no longer has any influence over the subsequent request so, theoretically, they should be dropped from the Origin header. In practise, that is only secure if trusted sites do not have open redirectors -- that might be too much to hope for.
It seems to me that the Origin spec is keeping the pre-redirect origins to cope with open redirectors, and implicitly hoping the order of origins can be used to ignore all but the last origin when necessary. Such an unstated hope interacts badly if OAuth adds an origin that isn't from a redirect.

--
James Manger

---

From: Adam Barth <[email-masked]>
Date: Sun, 27 Feb 2011 21:47:11 -0800

> That is true, Adam, but I was hoping for a bit more advice from the group knowing most about "Origin" and cross-site requests about the need to indicate the server that dynamically provided an opaq…

I'm not familiar enough with the details of OAuth to give you a
meaningful answer.  Last time I looked into Login CSRF issues with
OAuth, the protocol had a large problem and every implementation I
experimented with was trivially vulnerable.  I'd certainly recommend
doing something to prevent those attacks, but I'm unsure to what
extent the Origin header is the best solution available to you.

> What semantics are associated with the *order* of origins in an "Origin" HTTP request header value?

There are no semantics associated with the order of origins in the
Origin header.  To wit:

http://tools.ietf.org/html/draft-ietf-websec-origin-00#section-6.2

[[
6.2.  Semantics

   When included in an HTTP request, the Origin header indicates the
   origin(s) that caused the user agent to issue the request.

   For example, consider a user agent that executes scripts on behalf of
   origins.  If one of those scripts causes the user agent to issue an
   HTTP request, the user agent might wish to use the Origin header to
   inform the server that the request was issued by the script.

   In some cases, a number of origins contribute to causing the user
   agents to issue an HTTP request.  In those cases, the user agent can
   list all the origins in the Origin header.  For example, if the HTTP
   request was initially issued by one origin but then later redirected
   by another origin, the user agent might wish to inform the server
   that two origins were involved in causing the user agent to issue the
   request.
]]

Notice that the semantics does not depend on the order.

> The Origin spec implies (but doesn't explain) that there is some meaning to the order: a duplicate origin is omitted if it would be next to the same value (but included if there are intervening ori…

Those are user agent requirement for generating the header and not
related to the semantics, which are defined in Section 6.2.

> Perhaps it would be better for the Origin header to be specified as a *set* of origins, not a list. That is, state that order doesn't matter (and no duplicates are allowed). Would that hinder any u…

However we model the semantics of the header, when serialized on the
wire the origins will appear in some textual order.  The document
simple defines precisely how user agents ought to generate that
serialization.

> It seems to me that the Origin spec is keeping the pre-redirect origins to cope with open redirectors, and implicitly hoping the order of origins can be used to ignore all but the last origin when…

I didn't follow these paragraphs.  The specification is quite clear
about how the Origin header interacts with semantics.  If you have
specific questions, I can try to answer them, but I'm not sure there's
as specific a teleology as you ascribe above.

Adam

---

From: "Manger, James H" <[email-masked]>
Date: Mon, 28 Feb 2011 17:54:15 +1100

Thanks Adam.

> There are no semantics associated with the order of origins in the Origin header.

Great.

Ok, sort of.
So the text
  "no two consecutive serialized-origin productions in the grammar can be identical"
includes the word "consecutive" not for any semantic meaning, but because you think it might be easier for user-agents to implement the spec if they only have to compare an origin they are adding against the last existing origin, not all existing origins?

I can image a server X that is happy to accept a request redirected from a trusted server Y even if the request was originally caused by an unknown server Z. X totally trusts Y -- to not issue CSRF attacks, and to not be a conduit for CSRF attacks. However, when X receives
  Origin: Z Y
can it safely accept the request?

Not according to the semantics (6.2.) as unknown Z was somehow involved.
But it can be safe once 6.3 is also considered since any (potentially malicious) redirect from the unknown Z to X could not produce this ordering (it could produce "Origin: Y Z").

Giving user-agents precise instructions (MUSTs) is nice, but it does add semantics.

--
James Manger

---

From: Adam Barth <[email-masked]>
Date: Sun, 27 Feb 2011 23:03:23 -0800

> includes the word "consecutive" not for any semantic meaning, but because you think it might be easier for user-agents to implement the spec if they only have to compare an origin they are adding a…

That's just syntax.  Specifically, that sentence is restricting the
syntax that user agents can generate to a subset of the syntax
generated by the grammar.

> can it safely accept the request?

I'm not sure you've provided enough information in this hypothetical,
but I suspect the answer is no.

> Not according to the semantics (6.2.) as unknown Z was somehow involved.

Indeed.  In addition, without something like a Cookie, the HTTP
request might have originated from the attacker's computer and not
from a compliant user agent.

> But it can be safe once 6.3 is also considered since any (potentially malicious) redirect from the unknown Z to X could not produce this ordering (it could produce "Origin: Y Z").

I'm not sure that's accurate.

> Giving user-agents precise instructions (MUSTs) is nice, but it does add semantics.

The semantics are whatever we define them to be.  In this case, we've
defined the semantics to be order independent.

Adam