CSRF fails consistently for one user

I get one or two CSRF failures per day on ~600 sessions, however I’ve never been able to narrow down the cause and didn’t think much of it because of the low rate of failure. Today, I had a user fail the CSRF check 6 times on two different pages so I’d like to know how to fix this. Does anyone have any ideas why?

Below I’ve included the log sent to my email. I’ve bolded information that I think may be important or relevant (she’s on an IPv6 IP address and used the same device for all requests). I’ve also censored some information.

If it’s relevant, I’m on the latest Yii2 (2.0.12) and using Cloudflare.

2017-09-06 09:09:28

[108.162.249.94][-][dacc61335b3bbb071ec4ea8e43c6c7ff][error][yii\web\HttpException:400]

yii\web\BadRequestHttpException: Unable to verify your data

submission. in

/home/bookspro/booksproutapp/vendor/yiisoft/yii2/web/Controller.php:166

Stack trace:

#0

/home/bookspro/booksproutapp/frontend/controllers/SiteController.php(92):

yii\web\Controller->beforeAction(Object(yii\base\InlineAction))

#1

/home/bookspro/booksproutapp/vendor/yiisoft/yii2/base/Controller.php(154):

frontend\controllers\SiteController->beforeAction(Object(yii\base\InlineAction))

#2

/home/bookspro/booksproutapp/vendor/yiisoft/yii2/base/Module.php(523):

yii\base\Controller->runAction(‘contact’, Array)

#3

/home/bookspro/booksproutapp/vendor/yiisoft/yii2/web/Application.php(102):

yii\base\Module->runAction(‘site/contact’, Array)

#4

/home/bookspro/booksproutapp/vendor/yiisoft/yii2/base/Application.php(380):

yii\web\Application->handleRequest(Object(yii\web\Request))

#5 /home/bookspro/public_html/index.php(18):

yii\base\Application->run()

#6 {main}

2017-09-06 09:09:28

[108.162.249.94][-][dacc61335b3bbb071ec4ea8e43c6c7ff][info][application]

$_POST = [

'_frontend_csrf' =>

‘0U9jVU0fbg-gl7t4kADg1lKf8bv38sQYBPiSJvNHgqewykSHhS6KeAapE4-_9aS3QOQYilZBe4i_1x6nMDjP6A==’

]

$_SESSION = [

'__flash' => []

]

$_SERVER = [

'CONTENT_LENGTH' => '1111'


'CONTENT_TYPE' => 'application/x-www-form-urlencoded'


'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,/;q=0.8’

'HTTP_ACCEPT_ENCODING' => 'gzip'


'HTTP_ACCEPT_LANGUAGE' => 'en-au'


'HTTP_CF_CONNECTING_IP' =>

‘2001:8003:3d2e:8600:698a:XXXX:XXXX:XXXX’

'HTTP_CF_IPCOUNTRY' => 'AU'


'HTTP_CF_RAY' => '39a04a22cbd20b14-SYD'


'HTTP_CF_VISITOR' => '{\"scheme\":\"https\"}'


'HTTP_CONNECTION' => 'Keep-Alive'


'HTTP_HOST' => 'booksprout co'


'HTTP_ORIGIN' => 'https booksprout co'


'HTTP_REFERER' => 'https booksprout co/contact'


'HTTP_USER_AGENT' => [b]'Mozilla/5.0 (iPad; CPU OS 10_3_3 like Mac OS

X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60

Safari/602.1’[/b]

'HTTP_X_FORWARDED_FOR' =>

‘2001:8003:3d2e:8600:698a:XXXX:XXXX:XXXX’

'HTTP_X_FORWARDED_PROTO' => 'https'


'HTTP_X_HTTPS' => '1'


'PATH' => '/bin:/usr/bin'


'PHPRC' => '/home/bookspro/public_html'


'QUERY_STRING' => ''


'REDIRECT_HTTPS' => 'on'


'REDIRECT_SCRIPT_URI' => 'https booksprout co/contact'


'REDIRECT_SCRIPT_URL' => '/contact'


'REDIRECT_SSL_TLS_SNI' => 'booksprout co'


'REDIRECT_STATUS' => '200'


'REDIRECT_UNIQUE_ID' => 'Wa@7SKI8dZcGSkT7TjKxEQAAAso'


'REDIRECT_URL' => '/contact'


'REMOTE_ADDR' => '108.162.249.94'


'REMOTE_PORT' => '23955'


'REQUEST_METHOD' => 'POST'


'REQUEST_SCHEME' => 'https'


'REQUEST_URI' => '/contact'


'SCRIPT_FILENAME' => '/home/bookspro/public_html/index.php'


'SCRIPT_NAME' => '/index.php'


'SCRIPT_URI' => 'https booksprout co/contact'


'SCRIPT_URL' => '/contact'


'SERVER_ADDR' => '1.1.1.1'


'SERVER_ADMIN' => 'webmaster@booksprout co'


'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' => 'Wa@7SKI8dZcGSkT7TjKxEQAAAso'


'PHP_SELF' => '/index.php'


'REQUEST_TIME_FLOAT' => 1504688968.7715


'REQUEST_TIME' => 1504688968








'argv' => []


'argc' => 0

]

Any help on the subject will be greatly appreciated. Thank you!

Could be https://github.com/yiisoft/yii2/issues/14542

Thanks for the message, Sam. I’m relatively inexperienced in this space, but I don’t think he and I are having the same issue. Please correct me if wrong, but these are my justifications:

[list=1]

[*]My users get a #400 Unable to verify your data submission - not a 403 permission denied.

[*]I tried to reproduce his issue but could never generate a 403 error.

[*]If it were modsecurity causing the issue, users would be stopped before Yii code is executed. However, since I’m getting these errors via email, Yii code is being executed.

[/list]

  1. The issue I’ve linked causes 400.

  2. It may depend on a browser and luck (it takes time to generate token which is outside of ASCII set).

Just to make sure the correct issue was linked, in the one I’m looking at the user says:

Our error codes are different.

I’ve just tried in 4 different browsers (Windows 10 Chrome, Windows 10 Internet Expolorer, Android Chrome, and IOS Safari). On each I’ve refreshed the page 50 times (thus totaling 200 total refreshes). I have not yet come across an error.

Here’s the test code I’ve used to try and re-produce his issue:




<?php


namespace frontend\controllers;


use Yii;

use yii\web\Controller;


/**

 * TestController implements the CRUD actions for test stuff.

 */

class TestController extends Controller

{

    public function behaviors()

    {

        return [];

    }

		

		public function beforeAction($action) {

				if($action->id == 'index'){

					$this->enableCsrfValidation = false;

					$cookies = Yii::$app->response->cookies;

					$cookies->remove('_csrf');

					unset($cookies['_csrf']);

				}

				return parent::beforeAction($action);

		}

		

		public function actionIndex()

		{

				

		}

}




403 was from Apache module. If it were a browser, it would give you 400.

You won’t ever reproduce the issue if you’re turning CSRF validation off.

Sam I appreciate your patience in helping me, but I’m still not following. The code I’m using above is an exact copy/paste from the “What steps will reproduce the problem?” section of the issue referenced earlier. I was under the assumption that if I were to do exactly as he did, I’d be able to re-produce the 400 error if it’s the same problem.

How can I verify that it’s the same issue or not?

Ahhh! Right. Now I’ve got it. You’re not only disabling CSRF checking but deleting the token cookie (what for?) which may be set and used by another page:


public function beforeAction($action) {

    // for index action

    if ($action->id == 'index') {

        // don't validate CSRF

        $this->enableCsrfValidation = false;


        // delete CSRF cookie (why?)

        $cookies = Yii::$app->response->cookies;

        $cookies->remove('_csrf');

        unset($cookies['_csrf']);

    }

    return parent::beforeAction($action);

}

So in your case user is opening a form, it is setting a CSRF cookie. Then, in another tab, he’s opening index page which deletes token Cookie. Then submitting the form. Token is regenerated so value doesn’t match what was in the form.

To be honest, I’m merely copying and pasting the code from the issue you linked above. I have no idea why they did anything, because to me it also does not make any sense to disable CSRF, then delete the cookie. This is not my code and is most definitely not used in production with real users, I was just trying to re-produce the issue linked earlier to see if it was the same one that I am experiencing.

I think it’s best if we return to my initial question, because at this point I think both of us are confused by each other. I personally do not think the issue linked is relevant to it, and that’s what has caused our mutual confusion.

I still think it could be related.

Okay, I would like to dig a little deeper then and figure out how to fix it. Is there any test code/scenario you would recommend I try if not the one included in the bug you linked earlier?

Nope.