- From: Brad Hill <hillbrad@fb.com>
- Date: Sat, 10 Jan 2015 22:22:14 +0000
- To: "ietf-http-wg@w3.org" <ietf-http-wg@w3.org>
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 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. 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 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. 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. 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. 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. Brad Hill
Received on Saturday, 10 January 2015 22:23:28 UTC