W3C home > Mailing lists > Public > ietf-http-wg@w3.org > January to March 2015

Re: New header for "Fragment-Scope"?

From: Amos Jeffries <squid3@treenet.co.nz>
Date: Sun, 11 Jan 2015 15:26:03 +1300
Message-ID: <54B1DF3B.4030704@treenet.co.nz>
To: ietf-http-wg@w3.org
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 11/01/2015 11:22 a.m., Brad Hill wrote:
> Here's an example that I hope will clarify:
> 
> http://tools.ietf.org/html/rfc6749#section-4.2
> 
> 
> 
> In OAuth, an Access Token Request looks like the following:
> 
> GET 
> /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz&redirect_uri=
>
> 
https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
> Host: server.example.com
> 
> If the authorization server is willing to process this request, it 
> responds like so:
> 
> HTTP/1.1 302 Found Location: 
> https://client.example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz
>
> 
&token_type=example&expires_in=3600
> 


Bug 1) The use of Bearer / access_token in #fragment does not comply
with RFC 6750.

Only use as a query parameter is defined, and because of exactly this
type of security scoping problem. There are enough security problems
added just using them in query parameters (which *are* tied to the
client.example.com origin) without allowing the arbitrary un-tied use
that #fragment implies.


> 
> The fragment containing the access token is not sent with the
> subsequent HTTP request to client.example.com, but if
> client.example.com responds with text/html content, the user agent
> applies the fragment, which can be read by e.g. script in the DOM.

Which is explicitly the property difference between fragment and query
parameters.

Fragment is a form of URL-based cookie which persists between request
implictly and affects folowing traffic. Use of this type of storage
for OAuth tokens is explicitly forbidden by RFC 6750 section 5.3.

"Safeguard bearer tokens:  Client implementations MUST ensure that
      bearer tokens are not leaked to unintended parties, as they will
      be able to use them to gain access to protected resources.  This
      is the primary security consideration when using bearer tokens and
      underlies all the more specific recommendations that follow.
"
and

"Don't pass bearer tokens in page URLs:  Bearer tokens SHOULD NOT be
      passed in page URLs
"

What is the point of violating the OAuth Bearer specification by using
#fragment at all if you dont want its semantic properties?


> 
> The nature of OAuth and similar protocols is that the redirect
> location is passed in with the request (in this example, the
> redirect_uri paremeter). If that redirect_uri is maliciously
> modified, the server might send credentials to an incorrect host.
> The common mitigation to this is to whitelist the set of uris that
> server.example.com is willing to redirect to.
> 
> But even if server.example.com is only ever willing to redirect to 
> https://client.example.com/cb, what if there exists unknown
> processing logic at that endpoint (the attacker may add query
> string parameters not part of the whitelist, exploit additional
> client state like cookies, exploit differences in url parsing
> between client, sever and browser, etc., or perhaps the whitelist
> is only at the granularity of a server) such that additional
> redirects are triggered from client.example.com to evil.com?,

The use of #fragment explicitly opens the system to all of the top 3
security threats called out by OAuth Bearer spec:
 http://tools.ietf.org/html/rfc6750#section-5.1

OAuth (2.0 at least) is built on the assumption that there is *no*
malicious or intermediary processing interactions. If there are the
security of an entire OAuth Bearer system becomes null and void. This
is a well known property which has caused numerous long and bitter
arguments in the OAuth 2.0 WG.
(Please lets not go into all that in here, we have enough long threads
of our own and Erans' arguments about holes in the client processing
stacks are in the OAuth archive).

> 
> The UA issues a request for https://client.example.com/cb, and in
> this case gets a new 302 response with a redirect to evil.com,
> requests that, and then applies the fragment to the resulting
> text/html resource. Evil.com now has the access token.

Which is the behaviour explicitly imposed by the server when it opted
to use a custom #fragment style of transfer instead of the RFC 6750
defined ?query or the better options.

> 
> What Andrey and I are suggesting is that the initial 302 being sent
> by the OAuth authorization server could look like:
> 
> HTTP/1.1 302 Found Location: 
> https://client.example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz
>
> 
&token_type=example&expires_in=3600
> Fragment-Scope: same-origin
> 
> 
> This would instruct the UA that the fragment is only intended for 
> client.example.com, and should be discarded if client.example.com
> replies with another redirect to a different origin.
> 

Whereas the OAuth 2.0 WG defined that it shall be:

 HTTP/1.1 302 Found
 Location:
 https://client.example.com/cb?access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz
 &token_type=example&expires_in=3600

(sorry about the wrap)

Which explicitly
A) binds the access_token to the domain client.example.com, AND
B) ensures that no portion of it be stored and re-used by naive UA
process stacks on unrelated URLs even within the client.example.com
domain URL space.
C) only OAuth processing stack component(s) are explicitly coded to
persist the token between requests when implemented as per the OAuth spec.


> Note that server.example.com here is not returning a resource or 
> constructing a DOM, so there is no opportunity to apply parameters
> in the fetch algorithm, nor to rely on media-type specific handling
> of fragments. There isn't really even an OAuth "protocol" here to
> fix - it's riding entirely on top of HTTP semantics at this point.

FUD. A great many tools that use URI query parameters having nothing
to do with DOM in them. Lack of a DOM at either endpoint is no
justification for using #fragment over ?query. Quite the opposite,
lack of DOM makes it *easier* to use query parameters, as those
endpoints API often have direct access to the original URL string.

I recall that this was the explicit reason why query parameters were
left defined in RFC 6750 despite their known security impact. The
headers were not always avaiable to such tools even when the raw URL
string was.

> 
> For Facebook and other large OAuth providers, "client.example.com"
> is really thousands or tens of thousands of different endpoints.
> These have all kinds of various and sundry peculiarities, but one
> of the most common is redirect behavior like this.  We would like
> to be able, in the role of authorization server, enlist the
> assistance of the user agent to mitigate many these vulnerabilities
> by providing additional information about how to dispose of a
> sensitive fragment when chaining 3xx responses.

You would be able to mitigate many, many more of the security issues
by actually following the RFC 6750 specification behaviour.

That includes resolving or mitigating security issues interacting with
software which is not implementing your custom Fragment-Scope header.

Amos

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (MingW32)

iQEcBAEBAgAGBQJUsd86AAoJELJo5wb/XPRjY3YIANwghuc9f99uNjNfm9seggLw
qXs7Lw3p8TPAawR9pPQzba3FTcdIgyF2P9ThBd8BPIt4Yefcnponf+R8CDpAxegZ
bGTc2YMZ2SLSKyEPbLDcryboAziF2YL9agg0LVzWJ13buOeI7ZjB+k8zOKYSEzOQ
kco8f7j6hXIsLApKN9u9vtLJEfRhPGr6XTkxoM6r/vp9CAxW5sItqRzzztMvU/g4
rBk15zjqv/RbGHlN+afTt7sRHgopN7UC2JO5Aar5IKCDImBAPtLL3OFXps+pG9gB
dJMa9oHMTHM0R6J7LQu9JeQq+3sTPBk8+S+vKUKpvC4oScPDnqcTfs0ja/b/Fi8=
=LpeB
-----END PGP SIGNATURE-----
Received on Sunday, 11 January 2015 02:26:49 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 1 March 2016 11:11:36 UTC