oauth-2.0dotnetopenauthwindows-live-idliveconnectlive-connect-sdk

Serious replay attack issue of Live Connect OAuth2? Why is the authorization code allowed to be used more than once?


Firstly thanks for your time. I have a serious concern about Live Connect's OAuth2 API.

I follows this, and using DotNetOpenAuth to implement/integrate LiveId authentication/authorization for our federated identity & access management system.

http://msdn.microsoft.com/en-us/library/live/hh243647.aspx#authcodegrant

Everything is working fine for quite a long time. But now I'm having a serious trouble when fixing the replay attack issue for LiveId login module. Let's take a look at the Authorization code grant flow from the above article.

"*4. The user agent calls the client with the redirection URI, which includes an authorization code and any local state that was provided by the client. For example: ...Callback.htm?code=AUTHORIZATION_CODE. 5. The client requests an access token from the authorization server's token endpoint by using its client credentials for authentication, and includes the authorization code that was received in the previous step. The client includes the redirection URI that was used to obtain the authorization code for verification.*"

Right after the step 4, Live Connect OAuth2 server returns to my callback endpoint with the authorization code & state, like the following:

https://ssss.myapp.com:443/liveid/consume.idp?code=406dd558-0cda-50cc-bd37-d964ec29fbb3&state=uvygsnd3gba0jwi315kdyccs

Problem is, that authorization code could be used more than once. So it leads to the serious replay attack issue, like the following scenario:

  1. User A when logging in to my application, chose LiveId to sign-in, then he's redirected to LiveId login page. He then logged in, Live Connect OAuth2 server returned to the callback endpoint with the code=xxx&state=yyy...user A then used this authorization code to obtain the access token...

  2. User B when logging in to my application, chose LiveId to sign-in, he then logged in at LiveId's login page. Live Connect OAuth2 server now return with code=kkk&state=ggg

If I this time, use some tools like Webscarab to capture the response/request, then change the return from OAuth2 server to code=xxx&state=ggg (the old authorization code was given to user A, not B). Then after that, requesting for access token using this replay authorization code was going through smoothly. And guess what? I received again the ACCESS TOKEN which was given to user A before...and finally, user B can logging into my application as user A.

Please be noticed that, applying the same replay attacking like above for Google OAuth2 server, I received bad request error from the server, Google OAuth2 authorization code never could be used more than once. And the code flow or exactly, the implementation for Google login & LiveId login are exactly the same.

I used DotNetOpenAuth.OAuth2.WebServerClient to implement the OAuth2 authenticating flow for both of Google & LiveId. Again, exactly the same code, but Google OAuth2 server returned "bad request" when authorization code is reused, but LiveId returned the old access token of the previous user.

This is a serious security problem. Hope you guys have some ideas on this. Or hopefully I'm wrong on some points. Please point it out.

Thanks very much in advance, Phuc Le.


Solution

  • The OAuth 2 spec is quite clear here:

    If an authorization code is used more than once, the authorization server MUST deny the request and SHOULD revoke (when possible) all tokens previously issued based on that authorization code.

    This is for the exact reasons you mentioned above.

    In your case, you should notify your provider of this issue.

    Meanwhile, you could implement a cache of used authorization codes on client side and check for already issued codes. Note thate this could also produce false positives in the occasion that the provider randomly generated the same code for two different users (which might be quite unlikely, depending on the implementation).