yiisoft / yii2-authclient

Yii 2 authclient extension.
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
463 stars 246 forks source link

Invalid auth state parameter. #228

Closed des1roer closed 6 years ago

des1roer commented 6 years ago

in \yii\authclient\OAuth2::fetchAccessToken sometimes sessionStorage incorrect return $authState

yii-bot commented 6 years ago

Thanks for posting in our issue tracker. In order to properly assist you, we need additional information:

Thanks!

This is an automated comment, triggered by adding the label status:need more info.

cleippi commented 6 years ago

I've always seen numerous "invalid auth state parameter" errors on my application for the last 1-2 years. I've always thought it was normal, given the website load. However in the last week or so I've seen a far higher number of them. I'll do my best to add more details below.

When does the issue occur?

On Facebook login. It's the only auth method I have enabled so I cannot comment if it's Facebook specific or not.

What do you see?

I receive an error log as follows (personal information redacted)

2018-06-15 04:07:25
[][-][][error][yii\web\HttpException:400]
yii\web\HttpException: Invalid auth state parameter. in
/home/bookspro/booksproutapp/vendor/yiisoft/yii2-authclient/src/OAuth2.php:106
Stack trace:
#0
/home/bookspro/booksproutapp/vendor/yiisoft/yii2-authclient/src/clients/Facebook.php(145):
yii\authclient\OAuth2->fetchAccessToken('...', Array)
#1
/home/bookspro/booksproutapp/vendor/yiisoft/yii2-authclient/src/AuthAction.php(392):
yii\authclient\clients\Facebook->fetchAccessToken('...')
#2
/home/bookspro/booksproutapp/vendor/yiisoft/yii2-authclient/src/AuthAction.php(209):
yii\authclient\AuthAction->authOAuth2(Object(yii\authclient\clients\Facebook))
#3
/home/bookspro/booksproutapp/vendor/yiisoft/yii2-authclient/src/AuthAction.php(194):
yii\authclient\AuthAction->auth(Object(yii\authclient\clients\Facebook))
#4 [internal function]: yii\authclient\AuthAction->run()
#5
/home/bookspro/booksproutapp/vendor/yiisoft/yii2/base/Action.php(94):
call_user_func_array(Array, Array)
#6
/home/bookspro/booksproutapp/vendor/yiisoft/yii2/base/Controller.php(157):
yii\base\Action->runWithParams(Array)
#7
/home/bookspro/booksproutapp/vendor/yiisoft/yii2/base/Module.php(528):
yii\base\Controller->runAction('social-login', Array)
#8
/home/bookspro/booksproutapp/vendor/yiisoft/yii2/web/Application.php(103):
yii\base\Module->runAction('site/social-log...', Array)
#9
/home/bookspro/booksproutapp/vendor/yiisoft/yii2/base/Application.php(386):
yii\web\Application->handleRequest(Object(yii\web\Request))
#10 /home/bookspro/public_html/index.php(18):
yii\base\Application->run()
#11 {main}
2018-06-15 04:07:25
[][-][][info][application]
$_GET = [
    'authclient' => 'facebook'
    'code' =>
'XXXXXXXX'
    'state' =>
'XXXXXXX'
]

$_POST = []

$_FILES = []

$_COOKIE = [
    '__cfduid' => 'XXXXXXXXXX'
    'PHPSESSID' => 'XXXXXXXXXX'
    '_frontend_csrf' =>
'XXXXXXXXXX:2:{i:0;s:14:\"_frontend_csrf\";i:1;s:32:\"XXXXXXXXXX\";}'
    '_ga' => 'XXXXXXXXXX'
    '_gid' => 'XXXXXXXXXX'
]

$_SESSION = [
    '__flash' => []
]

$_SERVER = [
    'CONTEXT_DOCUMENT_ROOT' => '/home/bookspro/public_html'
    'CONTEXT_PREFIX' => ''
    'DOCUMENT_ROOT' => '/home/bookspro/public_html'
    'GATEWAY_INTERFACE' => 'CGI/1.1'
    'HTTPS' => 'on'
    'HTTP_ACCEPT' =>
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8'
    'HTTP_ACCEPT_ENCODING' => 'gzip'
    'HTTP_ACCEPT_LANGUAGE' => 'en-US'
    'HTTP_CF_CONNECTING_IP' => 'XXXXXXXXXX'
    'HTTP_CF_IPCOUNTRY' => 'US'
    'HTTP_CF_RAY' => 'XXXXXXXXXX'
    'HTTP_CF_VISITOR' => '{\"scheme\":\"https\"}'
    'HTTP_CONNECTION' => 'Keep-Alive'
    'HTTP_COOKIE' =>
'__cfduid=XXXXXXXXXX;
PHPSESSID=XXXXXXXXXX;
_frontend_csrf=XXXXXXXXXX%3A2%3A%7Bi%3A0%3Bs%3A14%3A%22_frontend_csrf%22%3Bi%3A1%3Bs%3A32%3A%XXXXXXXXXX%22%3B%7D;
_ga=XXXXXXXXXX; _gid=XXXXXXXXXX'
    'HTTP_HOST' => 'booksprout.co'
    'HTTP_REFERER' => 'http://m.facebook.com/'
    'HTTP_UPGRADE_INSECURE_REQUESTS' => '1'
    'HTTP_USER_AGENT' => 'Mozilla/5.0 (Linux; Android 8.0.0; SM-N950U
Build/R16NW; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0
Chrome/67.0.3396.87 Mobile Safari/537.36
[FB_IAB/FB4A;FBAV/177.0.0.25.105;]'
    'HTTP_X_FORWARDED_FOR' => 'XXXXXXXXXX'
    'HTTP_X_FORWARDED_PROTO' => 'https'
    'HTTP_X_HTTPS' => '1'
    'HTTP_X_REQUESTED_WITH' => 'com.facebook.katana'
    'PATH' => '/bin:/usr/bin'
    'PHPRC' => '/home/bookspro/public_html'
    'PHP_INI_SCAN_DIR' =>
'/opt/cpanel/ea-php70/root/etc:/opt/cpanel/ea-php70/root/etc/php.d:.'
    'QUERY_STRING' =>
'authclient=facebook&code=XXXXXXXXXX&state=XXXXXXXXXX'
    'REDIRECT_HTTPS' => 'on'
    'REDIRECT_QUERY_STRING' =>
'authclient=facebook&code=XXXXXXXXXX&state=XXXXXXXXXX'
    'REDIRECT_SCRIPT_URI' => 'https://booksprout.co/site/social-login'
    'REDIRECT_SCRIPT_URL' => '/site/social-login'
    'REDIRECT_SSL_TLS_SNI' => 'booksprout.co'
    'REDIRECT_STATUS' => '200'
    'REDIRECT_UNIQUE_ID' => 'XXXXXXXXXX'
    'REDIRECT_URL' => '/site/social-login'
    'REMOTE_ADDR' => 'XXXXXXXXXX'
    'REMOTE_PORT' => '9781'
    'REQUEST_METHOD' => 'GET'
    'REQUEST_SCHEME' => 'https'
    'REQUEST_URI' =>
'/site/social-login?authclient=facebook&code=XXXXXXXXXX&state=XXXXXXXXXX'
    'SCRIPT_FILENAME' => '/home/bookspro/public_html/index.php'
    'SCRIPT_NAME' => '/index.php'
    'SCRIPT_URI' => 'https://booksprout.co/site/social-login'
    'SCRIPT_URL' => '/site/social-login'
    'SERVER_ADDR' => 'XXXXXXXXXX'
    'SERVER_ADMIN' => 'XXXXXXXXXX'
    'SERVER_NAME' => 'booksprout.co'
    'SERVER_PORT' => '443'
    'SERVER_PROTOCOL' => 'HTTP/1.1'
    'SERVER_SIGNATURE' => ''
    'SERVER_SOFTWARE' => 'Apache/2.4'
    'SSL_TLS_SNI' => 'booksprout.co'
    'TZ' => 'America/Chicago'
    'UNIQUE_ID' => 'XXXXXXXXXX'
    'PHP_SELF' => '/index.php'
    'REQUEST_TIME_FLOAT' => 1529060845.499
    'REQUEST_TIME' => 1529060845
    'argv' => [
        0 =>
'authclient=facebook&code=XXXXXXXXXX&state=XXXXXXXXXX'
    ]
    'argc' => 1
]

What was the expected result?

I would expect that users can login via facebook.

If more information is needed, I will gladly supply it. I would be really happy for this error to go away.

cleippi commented 6 years ago

Upon further debugging, it appears that it's caused by this section of the code in yii\authclient\OAuth2:

public function fetchAccessToken($authCode, array $params = [])
    {
        if ($this->validateAuthState) {
            $authState = $this->getState('authState');
            $incomingRequest = Yii::$app->getRequest();
            $incomingState = $incomingRequest->get('state', $incomingRequest->post('state'));
            if (!isset($incomingState) || empty($authState) || strcmp($incomingState, $authState) !== 0) {
                throw new HttpException(400, 'Invalid auth state parameter.');
            }
            $this->removeState('authState');
        }

The if statement is triggered by empty($authState). $incomingState is set and appears like a valid value.

For session management I'm using yii\db\Session.

Judging by the error logs and reports from my users this problem affects specific users consistently (ie. they can't just try logging in again and have it work the second time).

It also might be helpful to note that I've consistently seen CSFR token errors on form submission: "Unable to verify your data submission." The two seem like they're possibly related.

Any ideas?

cleippi commented 6 years ago

Digging even deeper, it appears many of the problems are likely related to Facebook making a request instead of the user. Starting June 6th (when this bug was opened) I've started to see this user agent in many of the failures:

'HTTP_USER_AGENT' => 'facebookexternalhit/1.1'

Looks like Facebook is making the request for some users, which would obviously make the auth state parameter invalid.

This is likely the reason for the increase in errors I've seen, but not all as some have regular user agents.

cleippi commented 6 years ago

Because of the frequency of this error, I have temporarily disabled the auth state check as follows:

'authClientCollection' => [
    'class' => 'yii\authclient\Collection',
    'clients' => [
        'facebook' => [
            'class' => 'yii\authclient\clients\Facebook',
            'validateAuthState' => false, //TEMPORARY 
            'attributeNames' => ['id', 'email'],
            'clientId' => $params['facebook']['clientId'],
            'clientSecret' => $params['facebook']['clientSecret'],
        ],
    ],
],

Rather than actually fix the problem and have people login, I'm now seeing different more specific errors at roughly the same frequency.

yii\authclient\InvalidResponseException: Request failed with code:
400, message: {"error":{"message":"This authorization code has
expired.","type":"OAuthException","code":100,"fbtrace_id":"XXXXXXXX"}}
in
/home/bookspro/booksproutapp/vendor/yiisoft/yii2-authclient/src/BaseOAuth.php:221
yii\authclient\InvalidResponseException: Request failed with code:
400, message: {"error":{"message":"This authorization code has been
used.","type":"OAuthException","code":100,"fbtrace_id":"XXXXXXXX"}}
in
/home/bookspro/booksproutapp/vendor/yiisoft/yii2-authclient/src/BaseOAuth.php:221
samdark commented 6 years ago

Facebook making a request instead of the user

That's weird. Is it requesting any URLs by POST?

samdark commented 6 years ago

It's Facebook crawler that fetches OpenGraph info from pages but it should only use GET requests and with GET there's no CSRF token validation.

cleippi commented 6 years ago

From what I can tell, all the errors are via GET.

samdark commented 6 years ago

But CSRF isn't verified for GET...

cleippi commented 6 years ago

Yeah, I understand. My mention of CSRF was merely a sidenote in the chance that it is related since from what I understand, checking the validity of the Auth state is to prevent cross site attacks. You can disregard that if it's not relevant.

The main problem here appears to be that upon trying to use an invalid Facebook token, Facebook themselves are trying to make a request to a url that will only work for the user who originally tried logging in. It does not work for Facebook because they do not share a session with the user, and thus do not have an authstate in their session.

samdark commented 6 years ago

upon trying to use an invalid Facebook token, Facebook themselves are trying to make a request to a url

That doesn't sounds what the Facebook bot is stated to do...

cleippi commented 6 years ago

Yes, I agree. But I believe I've laid out a fairly compelling case to prove that it currently is doing just that. The above has happened for hundreds of users over the last week. It can't be a coincidence that most of the problems occur when a request is made by the Facebook user agent. It also can't be a coincidence that upon disabling the Auth state check a similar number of errors occur, all related to an invalid Facebook token.

samdark commented 6 years ago

That's still very weird and I have no idea about how to fix it.

cleippi commented 6 years ago

I have opened a bug report with Facebook to see if they have any input: https://developers.facebook.com/support/bugs/2182666902009838/

rrr-bot commented 6 years ago

Hi, We have the same issue with the state not being returned. In our case it depends on the Facebook Application version installed on the smartphone. For older application (we tested on version 176.0.0.33.87) Facebook Login links from the website were opened in the Facebook Application. And in this case Facebook didn't return the state if option "Open link externally" was turn off.

When we upgraded the application to the current version (177.0.0.57.105) links are opened in the browser. We couldn't find any way to force the phone to open them in the Facebook Application. And in this case state is returned correctly.

cleippi commented 6 years ago

Looks like this is a Facebook issue caused by an outdated app version (see the bug report here: https://developers.facebook.com/support/bugs/2182666902009838/). As users start updating their app we should see less and less of this problem.

We can close this issue.

vitaliykoziy commented 5 years ago

I got today same error :( Login via Chrome.

gurdeep-83ideas commented 4 years ago

Hi,

I'm also having the same error while trying to sign up or log in with Google.

omgkotofey commented 4 years ago

Hi,

I'm also having the same error, trying to log via Vkontakte auth client. 95% of application users can log correctly, but every day one or two login fails via 'Invalid auth state parameter.'

This problem actually not only for Facebook

samdark commented 4 years ago

@omgkotofey if you have idea about what's causing it and how to reproduce it, please open a separate issue. Without any info we're not able to reproduce / fix it.

djlift commented 4 years ago

I get this error too and i'm not using facebook at all.

samdark commented 4 years ago

@djlift same question as above. If you have details, please open a new issue.

ravithanki15 commented 4 years ago

Hello samdark

I have used yii2 authclient for login with google and facebook. Its working fine but last fews days i face error like "Invalid auth state" in login with google or facebook.

222

By some reserch and found solution that add validateAuthState' => false, this was worked in facebook but google not working.

Please help to resolve this.

Thank you.

samdark commented 4 years ago

@ravithanki15 please create separate issues with some details. Thanks.

ravithanki15 commented 4 years ago

@samdark please reply on https://github.com/yiisoft/yii2-authclient/issues/301

aeizumi commented 3 years ago

Was this issue already solved? with which solutions? because i'm facing the exception "Invalid auth state parameter." And i'm suspecting of these following lines (in yii\authclient\Oauth2).

if ($this->validateAuthState) { $authState = $this->getState('authState'); $incomingRequest = Yii::$app->getRequest(); $incomingState = $incomingRequest->get('state', $incomingRequest->post('state')); if (!isset($incomingState) || empty($authState) || strcmp($incomingState, $authState) !== 0) { throw new HttpException(400, 'Invalid auth state parameter.'); } $this->removeState('authState'); }

Thanks in advance.