thephpleague / oauth1-client

OAuth 1 Client
MIT License
968 stars 73 forks source link

OAuth_token is not equal to temporary_credentials->getIdentifier(), causing MITM warning #84

Open samjhill opened 7 years ago

samjhill commented 7 years ago

https://github.com/thephpleague/oauth1-client/blob/master/src/Client/Server/Server.php#L150

I extended Server for a different provider (SocialFlow.php file below), and after the auth redirect, I am given an OAuth_token, which I store in $_SESSION.

I also serialize and store the temporary_credentials the same way.

Then, I initialize it again, with the signature, for an endpoint run:

$server = new SocialFlow($args->client_credentials, unserialize($args->signature));
        try {
            $token = $server->getTokenCredentials(unserialize($args->temporary_credentials), $args->token_credentials['oauth_token'], $args->token_credentials['oauth_verifier']);
            return $server->getAccountsList($token);
        }...

The crux of the issue: the temporary_credentials that are given to me from SocialFlow don't have the same ID as the OAuth_token given to me after the auth redirect.

And I still get the warning Temporary identifier passed back by server does not match that of stored temporary credentials..

What am I doing wrong?


SocialFlow extends Server.php


namespace ...;

use League\OAuth1\Client\Credentials\TokenCredentials;
use League\OAuth1\Client\Server\Server;

class SocialFlow extends Server
{
    /**
     * {@inheritDoc}
     */
    public function urlTemporaryCredentials()
    {
        return 'https://www.socialflow.com/oauth/request_token';
    }

    /**
     * {@inheritDoc}
     */
    public function urlAuthorization()
    {
        return 'https://www.socialflow.com/oauth/authorize';
    }

    /**
     * {@inheritDoc}
     */
    public function urlTokenCredentials()
    {
        return 'https://www.socialflow.com/oauth/access_token';
    }

    /**
     * {@inheritDoc}
     */
    public function urlUserDetails()
    {
        return 'https://api.socialflow.com/account/list';
    }

    /**
     * {@inheritDoc}
     */
    public function userDetails($data, TokenCredentials $tokenCredentials)
    {
        return $data; //todo
    }

    /**
     * {@inheritDoc}
     */
    public function userUid($data, TokenCredentials $tokenCredentials)
    {
        return $data['id']; //todo
    }

    /**
     * {@inheritDoc}
     */
    public function userEmail($data, TokenCredentials $tokenCredentials)
    {
        return; //todo
    }

    /**
     * {@inheritDoc}
     */
    public function userScreenName($data, TokenCredentials $tokenCredentials)
    {
        return $data['name']; //todo
    }

    /**
     * Generic GET call using authorized credentials and specified path
     *
     * @param TokenCredentials $tokenCredentials
     * @param String $url
     *
     * @return array HTTP client response
     */
    protected function genericGetCall(TokenCredentials $tokenCredentials, $url)
    {
        $client = $this->createHttpClient();

        $headers = $this->getHeaders($tokenCredentials, 'GET', $url);
        print_r($headers);
        try {
            $response = $client->get($url, [
                'headers' => $headers,
            ]);
        } catch (BadResponseException $e) {
            $response = $e->getResponse();
            $body = $response->getBody();
            $statusCode = $response->getStatusCode();

            throw new \Exception(
                "Received error [$body] with status code [$statusCode] when retrieving token credentials."
            );
        }
        switch ($this->responseType) {
            case 'json':
                return json_decode((string) $response->getBody(), true);
                break;

            case 'xml':
                return simplexml_load_string((string) $response->getBody());
                break;

            case 'string':
                return [$response->getBody()];
                break;

            default:
                throw new \InvalidArgumentException("Invalid response type [{$this->responseType}].");
        }
    }

    public function getAccountsList(TokenCredentials $tokenCredentials)
    {
        return $this->genericGetCall($tokenCredentials, 'https://api.socialflow.com/account/list');
    }
}
dougblackjr commented 4 years ago

Having the same issue, would appreciate some help!

bencorlett commented 4 years ago

We're working on a new version right now - were there any updates to this by chance? I might try and reproduce it.

zerosonesfun commented 2 years ago

I am having a similar issue.

TypeError: League\OAuth1\Client\Server\Server::getTokenCredentials(): Argument #1 ($temporaryCredentials) must be of type League\OAuth1\Client\Credentials\TemporaryCredentials, bool given, defined in /league/oauth1-client/src/Server/Server.php:163
Stack trace:
League\OAuth1\Client\Server\Server->getTokenCredentials(false, 'La9eoAAAAAABGE6...', 'Ss4juqjoP8q9MHd...')

I'm not a professional developer. Does this mean the tokens aren't matching?

This only happens in iOS/Safari. Login works fine in Chrome.

bencorlett commented 2 years ago

@zerosonesfun your stack trace shows that you're passing false as the first argument to getTokenCredentials:

League\OAuth1\Client\Server\Server->getTokenCredentials(false, 'La9eoAAAAAABGE6...', 'Ss4juqjoP8q9MHd...')
                                                         ^^^

You'll need a developer to debug this further by stepping through your application's code.