- From: Amos Jeffries <squid3@treenet.co.nz>
- Date: Sun, 11 Jan 2015 15:26:03 +1300
- 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