Search code examples
phpdropboxcsrfdropbox-apidropbox-php

Dropbox API no longer working, CSRF mismatch


I use the Dropbox PHP SDK. Everything was working fine and suddenly the authentication process no longer works while no changes have been made to the code in this area.

I receive the error 'CSRF Mismatch'.

When looking at all CSRF tokens in the URL all seems to be correct:

https://www.dropbox.com/1/oauth2/authorize?locale=&client_id=redacted&response_type=code&redirect_uri=https%3A%2F%2Fmyapp.herokuapp.com%2Fdropbox%2Fcallback.php&state=L9yH1hf7pgiOY7j7fsFegA%3D%3D

https://myapp.herokuapp.com/dropbox/callback.php?state=L9yH1hf7pgiOY7j7fsFegA%3D%3D&code=redacted

CSRF Tokens match. Log reveals they are not though:

[15-May-2015 12:09:44 UTC] /dropbox-auth-finish: CSRF mismatch: Expected 'sW2Zy4OD7YBijNHaeCtyjQ==', got 'L9yH1hf7pgiOY7j7fsFegA=='

Solution

  • I spoke to Dropbox API support. They were very helpful and suggested a number of things:

    This error indicates that the state value returned to your redirect URI doesn't match the CSRF token that was stored in the session. The state value on your sample redirect URI matches the state value given to the /authorize URL though, so it looks like the issue is with the value stored in the session. A few things come to mind that might cause this:

    • Are you calling WebAuth.start multiple times for a single app authorization flow? If so, it's possible you're storing the CSRF token for one, but are browsing to the /authorize URL with the other.
    • Is your session storage not working correctly? The Dropbox PHP SDK uses the csrfTokenStore you pass to the WebAuth constructor. If that isn't able to store the new CSRF token, or is returning stale values, that could cause this mismatch.
    • Are you switching between different instances of your app, and so accessing different sessions?

    It turned out to be the first theorized problem. An AJAX call happened in the background which had a login check that also redirected to the authorize page, thus creating multiple requests. Once I disabled this the problem was gone.