Traveling with OAuth - Account Takeover on Booking.com
Relatively straight forward oauth hijack/account takeover flow with one interesting aspect in actually performing the login with the hijacked OAuth code.
The straight forward part is leaking the code from Facebook. Facebook’s side of the system only validates that teh redirect_uri
belongs to the appropriate domain. This isn’t terribly unexpected, but combined with an open-redirect somewhere within the Booking.com domain one can have the victim redirected to an attacker controlled location with the code in the URL.
Which is the first issue documented, an open redirect. I’m not exactly sure what Booking.com was thinking here but under the Dashboard there is an option to ‘Add a Display Name’ and clicking that takes you to a domain like the following: https://account.booking.com/oauth2/authorize?aid=123;client_id=[...];redirect_uri=[...];response_type=code;state=[...]
It looks like an OAuth flow page, though according to the author it just redirects off to the /mysettings/personal
endpoint. And that redirection happens based off of a Base64 encoded JSON content that is encoded into the state
parameter. The mysettings_path
from that JSON content is used to craft the redirect URL, and one can encoded their own URL pointing to another domain and have it redirect. So its an odd endpoint, but still an open redirect.
Now with the ability to steal codes used the open redirect, the challenge is logging in. Which did have a bit of an extra difficulty. Usually one could take the stolen code, and then during a legitimate OAuth flow tamper with their request, replacing the code returned by Facebook with the stolen code. The application iwll take that code and do its usual flow with it. The problem is that you send the redirect_uri
with the code
during the exchange process. The Booking server doesn’t know an abnormal redirect_uri
was used, so it sends along the normal one, and when Facebook sees that it throws back an error because the redirect_uri
doesn’t match the one used.
Fortunately for the authors here, the Booking mobile application had a bit of a weird process going on, where it would receive the code send it to booking.com backend, which would redirect it back to the back (using a deep link as its redirect), which would then send the code again to the server. When the code is passed to the backend for the second time, it sends a resultUri
parameter, this parameter is used as the redirect_uri
when exchanging the code. So by passing in the malicious redirect_uri
value in that request, the flow will complete as expected, granting an account takeover.