On 5/2/14 7:59 AM, Shane Tomlinson wrote:
> Is our OAuth implementation susceptible?

Nope, as Zach/Sean/pdehann figured out on #identity, we're ok, because
our OAuth server ignores the incoming redirect_uri= queryarg completely.
The browser will always be sent back to a URI provided by the original
RP app (when they registered the app and were given their client_id and
client_secret). The only two things parsed out of the incoming request
are state= and the list of desired scopes.

http://mashable.com/2014/05/02/oauth-openid-not-new-heartbleed/ and the
HN discussion at https://news.ycombinator.com/item?id=7685677 make a
little bit more sense than the upstream discussion
(http://tetraph.com/covert_redirect/oauth2_openid_covert_redirect.html).
The issue is also covered in the OAuth2.0 specs.

The vulnerability happens when two factors are present:

 1: the OAuth server allows the incoming request to influence the
    ultimate return URL. Typically the server mandates a pre-registered
    prefix on the URI, allowing the caller to vary the tail end but not
    the domain or the first few components of the path.
 2: the pre-registered RP target accidentally has some path (within that
    prefix) which can perform a redirect to an attacker-controlled site.
    These usually take a queryarg, but you could imagine someone using
    an escaped pathname segment.

The attacker gets the victim to click on a link which sends them to the
OAuth server with a URL like:

 oauth-server/login?clientid=GOOD&state=123&redirect_uri=PREFIX/redirect=evil

The OAuth server then asks the user to sign in and approve access by
client_id "GOOD" (some legitimate app). Assuming they approve, the OAuth
server then compares "PREFIX/redirect=evil" against the pre-registered
app's prefix (maybe "good.com/logged-in"), sees that "PREFIX/" matches,
and sends the browser off to "PREFIX/redirect=evil?state=123&code=456".
Then the RP performs a redirect to "evil", and the attacker's server
reads "code" out of the Referrer header.

Then the attacker goes back to the RP and starts their own login
process. Instead of following the redirect to the OAuth server, they
just redirect themselves back to the RP's return URL and add code=456
(i.e. "hi RP, I'm back from the OAuth server, they told me to tell you
code=456"). The RP uses the code as usual to fetch an OAuth token for
the victim, and associates it with the attacker's session. Now the
attacker can do anything that the RP is willing to do on behalf of the
victim.


As usual, flexibility and complexity are the enemies of security :).
Allowing the caller to specify the redirect_uri reduces coupling between
the RP and their registration at the OAuth server (e.g. you can
rearrange your site, moving the return URL to a new path, without
synchronizing the change with the OAuth server). But it's really bad to
let the caller specify it completely, because it could easily be an
attacker that's sending the user to the OAuth server (so they could do
redirect_uri=evil.com).

Constraining the redirect_uri by host (good) or prefix (better) limits
the attacker's options, but is still vulnerable to mistakes, like
someone on the RP site adding a path that does redirects. Forcing a
hard-coded pre-registered redirect_uri is best: it limits the
opportunity for mistakes down to a single RP path.

It'd be even better to not use HTTP redirects to pass the
authority-bearing values from the OAuth server back to the RP. The
result wouldn't look much like OAuth, though. Zach and I were sketching
this out.. I'll try to write it up soon.

cheers,
 -Brian
_______________________________________________
Dev-fxacct mailing list
[email protected]
https://mail.mozilla.org/listinfo/dev-fxacct

Reply via email to