zquestz/omniauth-google-oauth2 — pull request #98 by petergoldstein (2014-03-10 18:33:13+00:00)
Title: Add more secure hybrid authentication support, using the one-time code

While the hybrid authentication support introduced in pull request #50 allows a developer to implement hybrid authentication, it does so in such a way that introduces serious issues with the security of the protocol.

Specifically, by replacing the single-use code with a payload consisting of the access_token and an id_token it opens up the following issues:

1. Bearer token - the access_token is a bearer token, meaning that a malicious user can, with just the access_token and the application's client id, perform actions on Google on behalf of the authenticated user. Transmitting this token over the network, especially over a connection which is not required to be encrypted, is dangerous. Unlike the code parameter, one does not need the client secret to make use of the access_token. Thus this approach is very vulnerable to any sort of network sniffing.

2. Replay attacks - the combination of access_token and id_token can be used to authenticate a user multiple times. The combo will be good until the access_token expires or is revoked. So if a malicious user gets intercepts this data on the wire, they can use it to authenticate as the original user to the application. As the one-time code can only be used once, it is not vulnerable to this attack.

We can support hybrid authentication in a more secure fashion by using the code parameter. To do this we need to distinguish hybrid authentication callbacks from server-side callbacks, and provide the special 'postmessage' redirect_uri when verifying the code in the former case.

As a hybrid authentication callback should always be an AJAX request, while a server-side callback should never be an AJAX request, we can use an request.xhr? to distinguish the two cases. This PR implements hybrid authentication based on this distinction, and adds a corresponding spec.