[Uber] redirect_uri is difficult to do it right

I don’t have automation in my bug hunting, no sqlmap, sublist3r or jsparser. I tried, they just don’t work out for me. Other than a VPS server that help me to brute force certain endpoints to make a poc occasionally, all I have is a Burp Pro license on MBP. This is why you don’t see a lot of tools sharing or methodology sharing from me, not that I don’t want to share, it is because I don’t have those.

site:uber.com site:uberinternal.com site:yahoo.com is my hobby, looking through 15k of requests per day in Burp is daily job. Not going after reflective xss or stored xss except it’s right in my face. Test where the site leads me, check 10 variations of redirect_uri if the site use oauth. Most of my findings are irregular and spontaneous, hope this can answer the questions I keep getting from different channel.

But things that I can share among these irregularities, is the finding itself, I’m sharing a less-known Facebook redirect_uri trick today.

Back in 2016, Uber allow FB login in both login.uber.com and auth.uber.com, when we click login with Facebook button on the page, the flow:

https://facebook.com/xxxx?client_id=xxxxxx&redirect_uri=https%3a%2f%2fauth.uber.com%2flogin%3fnext_url=https%3A%2F%2Frush.uber.com%2Flogin%2F&state=m7QWxxPRNII4VGsCSog0xLJ2KF7e8ynpC2c_OAKkQQk%3D

https://auth.uber.com/login?next_url=https%3A%2F%2Frush.uber.com%2Flogin%2F&state=m7QWxxPRNII4VGsCSog0xLJ2KF7e8ynpC2c_OAKkQQk%3D#access_toekn=xxxx

https://rush.uber.com/login?….#access_token=xxxx

At first glance, it is difficult to spot the problem, (maybe easy for some trained eyes), the thing in the flow is, login endpoint allow further redirect to *.uber.com, because of how browser security works, 302 location header redirect will preserve the anything after hash in the URL. This lead to a conclusion that if it is possible to find open redirect in the next_url parameter, and redirect user to *.uber.com then to attacker controlled site, then we are able to steal the access token in URL.

Cause Uber is not accepting open redirect as valid submission anymore, finding one is not that difficult, one open redirect that still work today is https://login.uber.com/logout

It redirects base on Referer header, try it yourself.

<a href="https://login.uber.com/logout">Click to see</a>

 

If you are paying attention, now you should be able to use these information to figure an exploitation to achieve FB ATO in Uber. Write down your own exploit and try to see if we are sharing the same thoughts in below.

 

 

 

 

 

 

 

 

Here is my exploit.

<a href="https://facebook.com/xxxx?client_id=xxxxxx&redirect_uri=https%3a%2f%2fauth.uber.com%2flogin%3fnext_url=https%3A%2F%2Flogin.uber.com%2Flogout%2F&state=state">Click to leak</a>alert(location.hash)

Maybe you want a step by step explanation, but I rather keep that for you to figure this out, after you finish this tutorial  and all of my previous write-ups, come back here and you should able to know why exploit above work. (This learning process is much better than explaining it all out in this blog post, since there are dozens of article discussed about this already)

This was reported in late 2016. It was fixed promptly, and the fix is good, you should see how they fix it by yourself. I didn’t look back until early 2017.

By the time I look back, I figured Uber FB login is still hosting two whitelisted redirect_uri, they are https://auth.uber.com/login and https://login.uber.com/login

In theory, these should be difficult to exploit against since they have already patched the bug of open redirect, there is no way for me to redirect user to https://login.uber.com/logout again.

Here is the thing starts to get really interesting, let’s have a look at facebook redirect_uri, say, you have https://www.example.com/directory as whitelisted url. Then the variety of redirect_uri should be

redirect_uri=https%3a%2f%2fwww.example.com%2fdirectory -> Passed

redirect_uri=https%3a%2f%2fwww.example.com%2fdirectory%3fparameter%3dvalue -> Passed

redirect_uri=https%3a%2f%2fwww.example.com%2fdirectory%3fparameter%3dvalue%23 -> Failed since %23 in in the end of url

redirect_uri=https%3a%2f%2fwww.example.com%2fdirectory%2f..%2f..%2f -> Failed since it is using ../ to escape directory

All of the above redirect_uri variation is well known and have expected result, let’s look at something I found useful to exploit against Uber.

redirect_uri=https%3a%2f%2fwww.example.com%2fdirectory%252f..%252f..%252fescaped -> PASSED!!

After decoding in 302 response, the Location header now is

https://www.example.com/directory%2f..%2f..%2fescaped

 

Now this is the time to see whether the server accept the encoded slash %2f, usually the server will not accept this and return plain 400 forbidden or 404 not found. Luckily for me, login.uber.com happily accepted this as normalised the directory in server side

i.e.

https://login.uber.com/login -> present login page

https://login.uber.com/logout -> present logout page

https://login.uber.com/login%2f..%2f..%2flogout -> present logout page

 

Hence, combining Uber’s server side normalisation behaviour and Facebook’s acceptance of double url encoded slash, we have another way to takeover Uber’s FB account.

<a href="https://facebook.com/xxxx?client_id=xxxxxx&redirect_uri=https%3a%2f%2flogin.uber.com%2flogin%252f..%252f..%252flogout&state=state">Click to leak</a>alert(location.hash)

This was fixed by removing login.uber.com as the whitelist redirect_uri.

 

Thanks for reading.

7 thoughts on “[Uber] redirect_uri is difficult to do it right

  1. Would you say that all this could have been avoided if Uber used the authorization code instead of token?

    While #token=xxx leaks due to open redirects, ?code=xxx would not have allowed the leak even if there was an open redirect.

    Like

      1. Stealing the code is more difficult, it seems, since open redirects dont the url parameters.

        Do you think there is a reason why services still choose to use token, rather than code? The only one I can think of is that is is less troublesome?

        So far, ATO reports with flaws on the OAuth client, not provider, are exploitable because token is used. I don’t think I have seen any ones where ATO is possible when code is used. I might be wrong though.

        Like

      2. Yes it is more secure to use code to authorize user (in theory), since attacker will need authorization_code and client_secret to exchange an access token of user. However usually the vulnerable server will handle all these for us, like the flickr ATO I shared previously. https://ngailong.wordpress.com/2017/08/29/one-more-thing-to-check-for-sso-flickr-ato/

        It is rather difficult to judge which flow is more secure without any context, like in Flickr, it is using authorization code, but still there is a way to exploit the implementation if it is not implemented correctly.

        Like

Leave a comment