Hi, I would like to report an issue in Digits which allows attacker to bypass the callback_url validation of an application and thus takeover an account.
Digits is a part of the Fabric SDK which offers phone-based sign in. It also provides web login flow. In the navigation-based authentication flow, the OAuth credential data is passed to the specified callback URL (callback_url) after a user granted access to an application using HTTP 302 redirect. This parameter is supposed to be validated to match the registered domain of the application. Here's an example for Periscope:
callback_url=https://www.periscope.tv matches the application's registered domain, so no problem.
If we modify it: > https://www.digits.com/login?consumer_key=9I4iINIyd0R01qEPEwT9IC6RE&host=https%3A%2F%2Fwww.digits.com&callback_url=https://example.com
callback_url=https://example.com does not match the application's registered domain, thus the request is rejected.
Now, it is noticed that the validation is rather loose. For example, it parses the URL and compares only the hostname part. In other words, a URL with authority part is allowed (e.g. callback_url=https://email@example.com). It is still a solid validation because the hostname part is correctly handled (something like https://whatever\@www.periscope.tv won't work).
However, it is discovered that when outputting a non-ASCII character in the header, it will get converted to a question mark (?). This happens after the validation. Thus, attacker can bypass the validation by putting his/her own domain followed by a non-ASCII character in the authority part.
Here's how it works:
--------\ authority /\ hostname /
The URL is parsed and passes the validation because the hostname matches the registered domain.
--------\ hostname /-\ query /
Since the URL is outputted in the location header, %ff which is non-ASCII is converted. Now suddenly the hostname becomes attacker.com and everything after the question mark becomes the query part. Finally the victim will be redirected to attacker's site with victim's account's OAuth credential.
It affects every application that has integrated Digits, and even official application (Periscope). Attacker can abuse the flaw to login to victim's account on the affected applications.
Video demo: https://vimeo.com/150671313 (password: token)
The callback_url should discard the authority part before outputting.