yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
14.24k stars 6.91k forks source link

Tons of yii\web\BadRequestHttpException: Unable to verify your data submission #18514

Closed PELock closed 3 years ago

PELock commented 3 years ago

What steps will reproduce the problem?

I got tons of yii\web\BadRequestHttpException: Unable to verify your data submission in my logs since the latest updates, what is going on?

Additional info

2021-02-12 00:59:16 [176.59.73.204][-][-][error][yii\web\HttpException:400] yii\web\BadRequestHttpException: Unable to verify your data submission. in /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/web/Controller.php:209
Stack trace:
#0 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Controller.php(179): yii\web\Controller->beforeAction()
#1 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Module.php(534): yii\base\Controller->runAction()
#2 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/web/Application.php(104): yii\base\Module->runAction()
#3 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Application.php(392): yii\web\Application->handleRequest()
#4 /home/pelock/www/public_html/pelock.com/frontend/web/index.php(20): yii\base\Application->run()

The exception is thrown at:

    /**
     * {@inheritdoc}
     */
    public function beforeAction($action)
    {
        if (parent::beforeAction($action)) {
            if ($this->enableCsrfValidation && Yii::$app->getErrorHandler()->exception === null && !$this->request->validateCsrfToken()) {
                throw new BadRequestHttpException(Yii::t('yii', 'Unable to verify your data submission.'));
            }

            return true;
        }

        return false;
    }

My config:

$config = [
    'components' => [

        'session' => [
            'cookieParams' => [
                'httpOnly' => true,
                'secure' => true,
                'sameSite' => yii\web\Cookie::SAME_SITE_STRICT
            ]
        ],

        'request' => [
            // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
            'cookieValidationKey' => 'XXX',

            'csrfCookie' => [
                'httpOnly' => true,
                'secure' => true,
                'sameSite' => yii\web\Cookie::SAME_SITE_STRICT
            ],
        ],
    ],
];

But why now, after the update??? I know Chrome 88 rolled out, but is it related?

I'm looking at the logs right now, check this out:

2021-02-12 00:59:16 [XXX][-][-][error][yii\web\HttpException:400] yii\web\BadRequestHttpException: Unable to verify your data submission. in /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/web/Controller.php:209
Stack trace:
#0 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Controller.php(179): yii\web\Controller->beforeAction()
#1 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Module.php(534): yii\base\Controller->runAction()
#2 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/web/Application.php(104): yii\base\Module->runAction()
#3 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Application.php(392): yii\web\Application->handleRequest()
#4 /home/pelock/www/public_html/pelock.com/frontend/web/index.php(20): yii\base\Application->run()
#5 {main}
2021-02-12 00:59:16 [XXX][-][-][info][application] $_GET = [
    'group' => 'products'
    'name' => 'hash-calculator'
]

$_POST = [
    '_csrf' => 'KDXpDuKdX9Ad-jgo9oVQmiZC8jnf9nSD2qFZ6fKHUZl8ftk8g_AFmnStbE2C4RqiFQuYCeqROLqS7xCwmuMnzA=='
    'HashCalculatorForm' => [
        'value' => 'df24f3f8b8ec46f5857f547ff05584fa

'
        'crlf' => '1'
    ]
    'calculate-hash' => ''
]

$_FILES = []

$_COOKIE = []

$_SERVER = [
    'USER' => 'pelock'
    'HOME' => '/home/pelock'
    'HTTP_ACCEPT_LANGUAGE' => 'ru-RU,en-US;q=0.9'
    'HTTP_ACCEPT_ENCODING' => 'gzip, deflate'
    'HTTP_REFERER' => 'https://www.pelock.com/products/hash-calculator'
    'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8'
    'HTTP_USER_AGENT' => 'Mozilla/5.0 (Linux; U; Android 10; ru-ru; Redmi Note 9S Build/QKQ1.191215.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/71.0.3578.141 Mobile Safari/537.36 XiaoMi/MiuiBrowser/12.6.2-gn'
    'HTTP_CONTENT_TYPE' => 'application/x-www-form-urlencoded'
    'HTTP_UPGRADE_INSECURE_REQUESTS' => '1'
    'HTTP_ORIGIN' => 'null'
    'HTTP_CACHE_CONTROL' => 'max-age=0'
    'HTTP_CONTENT_LENGTH' => '251'
    'HTTP_HOST' => 'www.pelock.com'
    'SCRIPT_FILENAME' => '/home/pelock/www/public_html/pelock.com/frontend/web/index.php'
    'REDIRECT_STATUS' => '200'
    'SERVER_NAME' => 'www.pelock.com'
    'SERVER_PORT' => '443'
    'SERVER_ADDR' => 'XXX'
    'REMOTE_PORT' => 'XXX'
    'REMOTE_ADDR' => 'XXX'
    'SERVER_SOFTWARE' => 'nginx/1.19.6'
    'GATEWAY_INTERFACE' => 'CGI/1.1'
    'HTTPS' => 'on'
    'REQUEST_SCHEME' => 'https'
    'SERVER_PROTOCOL' => 'HTTP/2.0'
    'DOCUMENT_ROOT' => '/home/pelock/www/public_html/pelock.com/frontend/web'
    'DOCUMENT_URI' => '/index.php'
    'REQUEST_URI' => '/products/hash-calculator'
    'SCRIPT_NAME' => '/index.php'
    'CONTENT_LENGTH' => '251'
    'CONTENT_TYPE' => 'application/x-www-form-urlencoded'
    'REQUEST_METHOD' => 'POST'
    'QUERY_STRING' => ''
    'FCGI_ROLE' => 'RESPONDER'
    'PHP_SELF' => '/index.php'
    'REQUEST_TIME_FLOAT' => 1613091556.1384
    'REQUEST_TIME' => 1613091556
]

The cookies array is empty... But in other entries it's not:

2021-02-12 11:35:20 [XXX][-][-][error][yii\web\HttpException:400] yii\web\BadRequestHttpException: Unable to verify your data submission. in /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/web/Controller.php:209
Stack trace:
#0 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Controller.php(179): yii\web\Controller->beforeAction()
#1 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Module.php(534): yii\base\Controller->runAction()
#2 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/web/Application.php(104): yii\base\Module->runAction()
#3 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Application.php(392): yii\web\Application->handleRequest()
#4 /home/pelock/www/public_html/pelock.com/frontend/web/index.php(20): yii\base\Application->run()
#5 {main}
2021-02-12 11:35:20 [XXX][-][-][info][application] $_GET = []

$_POST = [
    '_csrf' => 'NoE5_KkQkpYs3ekiJlJfqabEjeieVUNb58KlqtPMavFn92y4nFPd2BuEoBQXYHKY6ozq0Kg4cC2znffTl_QDtA=='
    'CheckoutForm' => [
        'name' => '...'
    ]
]

$_FILES = []

$_COOKIE = [
    'crisp-client%2Fsession%2F022e663c-63c0-43f9-aea2-2d2215e75e4a' => 'session_7af7b028-74d0-4885-baf1-16f54ac79077'
    'PHPSESSID' => '5c8r8j250dj9v21ljf1v79et1a'
    '_csrf' => '36635741d3e942ee64945ae2f085a5092ddfa552c3f6531af675a3758cf3e9fda:2:{i:0;s:5:\"_csrf\";i:1;s:32:\"phNVEwgHG_kPoAtyoXAxvgh8uLzS1OiG\";}'
]
Q A
Yii version 2.0.40
PHP version 7.4.14
Operating system Debian 10
bizley commented 3 years ago

Using FF and testing a bit your website I can see this in console:

Cookie “__cfduid” has been rejected because it is in a cross-site context and its “SameSite” is “Lax” or “Strict”.

WIld guess is that it could be the source of problem.

PELock commented 3 years ago

It's from the CRISP chat cookie. Not related to Yii2.

bizley commented 3 years ago

Ok. From which version of Yii you have upgraded to 2.0.40? Is changing back to the previous one fixes the problem in Chrome 88?

yii-bot commented 3 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.

samdark commented 3 years ago

Related to the following:

The case in this issue is different though.

PELock commented 3 years ago

I have upgraded from 2.0.38 but from the logs I was able to identify the same errors from time to time, but since upgrade to 2.0.40 I got a whole list of these errors in logs.

I have temporarily disabled csrf validation, but the problem is I cannot reproduce this error myself, I'm not sure what's the reason, I suspect it could have something to do with public release of Chrome 88.

Strange thing is in some of those requests, the COOKIE array is completely empty, so it's completely valid to reject the request based on csrf validation, right? But why would the cookies be empty?

samdark commented 3 years ago

Strange thing is in some of those requests, the COOKIE array is completely empty, so it's completely valid to reject the request based on csrf validation, right?

Yes, absolutely.

But why would the cookies be empty?

Many reasons. If no real user ever complained, it could be that a bot is masking for a user and doesn't read cookies for whatever reason (despite it being a simple task). Or it could be misconfiguration in case you have multiple domains. Or some kind of a proxy like CloudFlare that kills the cookie.

samdark commented 3 years ago

I have upgraded from 2.0.38 but from the logs I was able to identify the same errors from time to time, but since upgrade to 2.0.40 I got a whole list of these errors in logs.

Can you temporarily downgrade to check if the rate of these errors changes?

ailmanki commented 3 years ago

I would check for parent::init which has changed in the controllers. Although that was in 2.0.35 https://github.com/yiisoft/yii2/blob/master/framework/UPGRADE.md#upgrade-from-yii-2035

PELock commented 3 years ago

I will put a logging code inside Yii2 code to catch those events and log as many details as possible.

PELock commented 3 years ago

I put this in web\Controller.php:

    /**
     * {@inheritdoc}
     */
    public function beforeAction($action)
    {
        if (parent::beforeAction($action)) {
            if ($this->enableCsrfValidation && Yii::$app->getErrorHandler()->exception === null && !$this->request->validateCsrfToken()) {

                \Yii::error("CSRF-FAIL");
                \Yii::error(var_export($this->enableCsrfValidation, true));
                \Yii::error(var_export(Yii::$app->getErrorHandler()->exception, true));
                \Yii::error(var_export($this->request->validateCsrfToken(), true));
                \Yii::error(var_export($this->request->getCsrfToken(), true));
                \Yii::error(var_export($this->request->getMethod(), true));
                \Yii::error(var_export($this->request, true));

                throw new BadRequestHttpException(Yii::t('yii', 'Unable to verify your data submission.'));
            }

            return true;
        }

        return false;
    }

It seems $this->request->validateCsrfToken() fails (false)

2021-02-12 19:53:51 [82.145.220.195][-][-][error][application] CSRF-FAIL
2021-02-12 19:53:51 [82.145.220.195][-][-][error][application] true
2021-02-12 19:53:51 [82.145.220.195][-][-][error][application] NULL
2021-02-12 19:53:51 [82.145.220.195][-][-][error][application] false
2021-02-12 19:53:51 [82.145.220.195][-][-][error][application] 'w2vQpHmzDVwa9sWYdKtbOBH3jNJEkNkgMSE3r_pDkKu3JIicKMAgJFO_it4zwDQJRb3JigHlsRJkbA7Cw3Lp7w=='
2021-02-12 19:53:51 [82.145.220.195][-][-][error][application] 'POST'
2021-02-12 19:53:51 [82.145.220.195][-][-][error][application] yii\web\Request::__set_state(array(
   'enableCsrfValidation' => true,
   'csrfParam' => '_csrf',
   'csrfCookie' => 
  array (
    'httpOnly' => true,
    'secure' => true,
    'sameSite' => 'Strict',
  ),
   'enableCsrfCookie' => true,
   'enableCookieValidation' => true,
   'cookieValidationKey' => 'XXX',
   'methodParam' => '_method',
   'parsers' => 
  array (
  ),
   'trustedHosts' => 
  array (
  ),
   'secureHeaders' => 
  array (
    0 => 'X-Forwarded-For',
    1 => 'X-Forwarded-Host',
    2 => 'X-Forwarded-Proto',
    3 => 'Front-End-Https',
    4 => 'X-Rewrite-Url',
  ),
   'ipHeaders' => 
  array (
    0 => 'X-Forwarded-For',
  ),
   'secureProtocolHeaders' => 
  array (
    'X-Forwarded-Proto' => 
    array (
      0 => 'https',
    ),
    'Front-End-Https' => 
    array (
      0 => 'on',
    ),
  ),
   '_cookies' => 
  yii\web\CookieCollection::__set_state(array(
     'readOnly' => true,
     '_cookies' => 
    array (
    ),
  )),
   '_headers' => 
  yii\web\HeaderCollection::__set_state(array(
     '_headers' => 
    array (
      'accept-encoding' => 
      array (
        0 => 'gzip, deflate',
      ),
      'cache-control' => 
      array (
        0 => 'max-age=0',
      ),
      'sec-fetch-user' => 
      array (
        0 => '?1',
      ),
      'origin' => 
      array (
        0 => 'https://www.pelock.com',
      ),
      'user-agent' => 
      array (
        0 => 'Mozilla/5.0 (Linux; U; Android 10; M2004J19C Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/88.0.4324.152 Mobile Safari/537.36 OPR/53.2.2254.55976',
      ),
      'referer' => 
      array (
        0 => 'https://www.pelock.com/products/pubg-mobile-config-encoder-decoder',
      ),
      'sec-fetch-mode' => 
      array (
        0 => 'navigate',
      ),
      'save-data' => 
      array (
        0 => 'on',
      ),
      'content-type' => 
      array (
        0 => 'application/x-www-form-urlencoded',
      ),
      'accept' => 
      array (
        0 => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9,image/webp',
      ),
      'sec-fetch-site' => 
      array (
        0 => 'same-origin',
      ),
      'sec-fetch-dest' => 
      array (
        0 => 'document',
      ),
      'accept-language' => 
      array (
        0 => 'en-US,en;q=0.9',
      ),
      'content-length' => 
      array (
        0 => '1709',
      ),
      'upgrade-insecure-requests' => 
      array (
        0 => '1',
      ),
      'host' => 
      array (
        0 => 'www.pelock.com',
      ),
    ),
  )),
   '_rawBody' => NULL,
   '_bodyParams' => 
  array (
    '_csrf' => 'Q04tY3cUSBx41xCKqN2SRUYOB6Mt2yEm9kbcBFwceaQtL2InQy0LcE29Q9X7hKs3AX0-9HeWaGOsN5I0K1U_7w==',
    'PubgEncodeForm' => 
    array (
      'input' => '+CVars=r.UserQualitySetting=1
+CVars=r.UserShadowSwitch=1
+CVars=r.ShadowQuality=0
+CVars=r.MobileContentScaleFactor=0.75
+CVars=r.UserVulkanSetting=0
+CVars=r.MobileHDR=0.0
+CVars=r.Mobile.SceneColorFormat=0.0
+CVars=r.Mobile.EnablePPR=0.0
+CVars=r.Shadow.MaxCSMResolution=720
+CVars=r.MaterialQualitySuperHigh=0.0
+CVars=r.UserHDRSetting=0
+CVars=r.ACESStyle=1
+CVars=r.UserMSAASetting=0
+CVars=r.DefaultFeature.AntiAliasing=0.0
+CVars=r.MobileMSAA=0
+CVars=r.MSAACount=0
+CVars=r.MaterialQualityLevel=0
+CVars=r.Shadow.CSM.MaxMobileCascades=0
+CVars=r.Shadow.DistanceScale=0
+CVars=r.Mobile.DynamicObjectShadow=0
+CVars=r.DepthOfFieldQuality=0
+CVars=r.RefractionQuality=0
+CVars=r.StaticMeshLODDistanceScale=1.3
+CVars=foliage.LODDistanceScale=0.6
+CVars=foliage.MinLOD=0
+CVars=r.DetailMode=0
+CVars=r.MaxAnisotropy=1
+CVars=r.Streaming.PoolSize=200
+CVars=r.EmitterSpawnRateScale=0.5
+CVars=r.ParticleLODBias=2
+CVars=r.MobileNumDynamicPointLights=1
+CVars=diy.SetDecalBakingRTSizeInLobby=720
+CVars=r.PUBGVersion=5
+CVars=r.MobileSimpleShader=0
+CVars=r.PUBGDeviceFPSLow=60
+CVars=r.PUBGDeviceFPSMid=60
+CVars=r.PUBGDeviceFPSHigh=60',
      'output' => '',
    ),
    'encode-button' => '',
  ),
   '_queryParams' => NULL,
   '_hostInfo' => NULL,
   '_hostName' => NULL,
   '_baseUrl' => '',
   '_scriptUrl' => '/index.php',
   '_scriptFile' => NULL,
   '_pathInfo' => 'products/pubg-mobile-config-encoder-decoder',
   '_url' => '/products/pubg-mobile-config-encoder-decoder',
   '_port' => NULL,
   '_securePort' => NULL,
   '_contentTypes' => NULL,
   '_languages' => NULL,
   '_csrfToken' => 'w2vQpHmzDVwa9sWYdKtbOBH3jNJEkNkgMSE3r_pDkKu3JIicKMAgJFO_it4zwDQJRb3JigHlsRJkbA7Cw3Lp7w==',
   '_secureForwardedHeaderParts' => NULL,
   '_isConsoleRequest' => NULL,
   '_events' => 
  array (
  ),
   '_eventWildcards' => 
  array (
  ),
   '_behaviors' => NULL,
   '_scriptFile' => NULL,
))
2021-02-12 19:53:51 [82.145.220.195][-][-][error][yii\web\HttpException:400] yii\web\BadRequestHttpException: Unable to verify your data submission. in /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/web/Controller.php:218
...
Stack trace: 
...
$_COOKIE = []

The IP address of the request in whois.sc database returns n42-08-08.opera-mini.net, maybe there's something wrong with Opera Mini browser? Again cookies array is empty, so no wonder it fails.

This is one dump, waiting for another shot.

PELock commented 3 years ago

I wonder if that's not some caching server of Opera Mini? Waiting for more data.

PELock commented 3 years ago

Another failure from 82.145.222.69 again Opera Mini. Again cookies not set.

'HTTP_USER_AGENT' => 'Mozilla/5.0 (Linux; U; Android 10; M2004J19C Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/88.0.4324.152 Mobile Safari/537.36 OPR/53.2.2254.55976'

Isn't it that it this mobile browser doesn't support secure or HTTP only cookies? So the CSRF token is not set at all, and when form is submitted it just fails (like its suppose to do)?

PELock commented 3 years ago

I got this Opera Mini com.opera.mini.native_53.2.2254.55976-532055976_minAPI17(armeabi-v7a)(nodpi)_apkmirror.com

https://www.apkmirror.com/apk/opera-software-asa/opera-mini/opera-mini-53-2-2254-55976-release/opera-mini-fast-web-browser-53-2-2254-55976-android-apk-download/download/

and it works fine...

and it works just fine ;)

PELock commented 3 years ago

Got another one, this time from diff IP range. COOKIES array is empty, again.

It seems like Yii2 doesn't save the CSRF cookie every time. There's something wrong.

PELock commented 3 years ago

This error happens on pages with multiple forms, I wonder if that matters...? Any help at all?

bizley commented 3 years ago

Hmm, is token overriden on each form addition? I need to check this. Thank you for heavy tests, always helpful.

PELock commented 3 years ago

I don't know, the token is just not there (not in cookies), but it's passed as a parameter in POST request (so it's been generated, right?), I will put some hooks to see if it was set and then removed when the form was posted. It seems like some strange cookie thing bug.

bizley commented 3 years ago

Ok, I've checked and each additional form on the page is not changing the token. The point of failure can be like following:

  1. Token is generated (with beginForm, cookie is sent).
  2. Data is posted.
  3. On receiving the data cookie is not found so new token is generated and both values obviously not match.

So it all narrows down to cookie processing between a browser and an app and not something Yii can help with (unless it's a matter of misconfiguration). Temporary solution might be setting enableCsrfCookie in Request to false (but keep in mind that it degrades the performance since the session is restarted every time).

Anyway, still looking for a solution.

bizley commented 3 years ago

Just to make sure - could you paste here your nginx configuration for that domain?

PELock commented 3 years ago

Hmm, this is very strange, could that be that someone is trying to submit the form without visiting the site at the first place? But if that fails, I would personally stop trying, but I have those errors more in the logs

bizley commented 3 years ago

I don't think so since there is _csrf field in POST. In your last example it's clear that CSRF token has been changed between sending and receiving the data (see different _csrf - sent - and _csrfToken - stored in Request object - values).

PELock commented 3 years ago

I have to disable csrf because it fails everywhere... even when CSRF token is passed in cookies. Let me think. I have upgraded to PHP 8 yesterday, Let me review the logs again.

PELock commented 3 years ago

Single request

Dumped request:

   '_cookies' => 
  yii\web\CookieCollection::__set_state(array(
     'readOnly' => true,
     '_cookies' => 
    array (
      '_csrf' => 
      yii\web\Cookie::__set_state(array(
         'name' => '_csrf',
         'value' => 'LR7qZKKdoAjC95g3rYSDffKTvxyhLgjz',
         'domain' => '',
         'expire' => NULL,
         'path' => '/',
         'secure' => false,
         'httpOnly' => true,
         'sameSite' => NULL,
      )),
    ),
  )),
   '_headers' => 
  yii\web\HeaderCollection::__set_state(array(
     '_headers' => 
    array (
      'cookie' => 
      array (
        0 => '_csrf=18419c28117ba1d80938ad7fab3e39c849d882bd1278215f3a21f651db42f307a%3A2%3A%7Bi%3A0%3Bs%3A5%3A%22_csrf%22%3Bi%3A1%3Bs%3A32%3A%22LR7qZKKdoAjC95g3rYSDffKTvxyhLgjz%22%3B%7D; crisp-client%2Fsession%2F022e663c-63c0-43f9-aea2-2d2215e75e4a=session_0759c835-fe70-4f9b-b360-28f70dea7c4b',
      ),

Notice the 'secure' is set to false, but in my configuration I have this set to true.

CSRF value after URL decode:

18419c28117ba1d80938ad7fab3e39c849d882bd1278215f3a21f651db42f307a:2:{i:0;s:5:"_csrf";i:1;s:32:"LR7qZKKdoAjC95g3rYSDffKTvxyhLgjz";}

Form data:

   '_bodyParams' => 
  array (
    '_csrf' => 'mKPcfifrKy8UZhclfKnU7ENnCgThoiyyNkvOU6zSuwv09q9MV6RdV3YBfmg44YXaAiNsQ8ybfOJwIfsJ1IL_TQ==',

Cookie array:

$_COOKIE = [
    '_csrf' => '18419c28117ba1d80938ad7fab3e39c849d882bd1278215f3a21f651db42f307a:2:{i:0;s:5:\"_csrf\";i:1;s:32:\"LR7qZKKdoAjC95g3rYSDffKTvxyhLgjz\";}'
    'crisp-client%2Fsession%2F022e663c-63c0-43f9-aea2-2d2215e75e4a' => 'session_0759c835-fe70-4f9b-b360-28f70dea7c4b'
]
bizley commented 3 years ago

Hmm, yes, it looks like your config was not used at all...

PELock commented 3 years ago

Let me put some more hooks in Yii2 code. I will not sleep if I don't find it :), wait for the logs.

bizley commented 3 years ago

Scratch that, it's fine - request cookie collection does not rebuild cookies with the aforementioned configuration, it's using the default one since it's value that we want. And btw you have your cookie there in $_COOKIE so it's not a log bringing anything here.

PELock commented 3 years ago

My config from /frontend/config/main-local.php

<?php

$config = [
    'components' => [

        'session' => [
            'cookieParams' => [
                'httpOnly' => true,
                'secure' => true,
                'sameSite' => yii\web\Cookie::SAME_SITE_STRICT
            ]
        ],

        'request' => [
            // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
            'cookieValidationKey' => 'xxx',

            'csrfCookie' => [
                'httpOnly' => true,
                'secure' => true,
                'sameSite' => yii\web\Cookie::SAME_SITE_STRICT
            ],
        ],
    ],
];
PELock commented 3 years ago

I have modified /web/Request.php

    /**
     * Validates CSRF token.
     *
     * @param string $clientSuppliedToken The masked client-supplied token.
     * @param string $trueToken The masked true token.
     * @return bool
     */
    private function validateCsrfTokenInternal($clientSuppliedToken, $trueToken)
    {
        if (!is_string($clientSuppliedToken)) {

            \Yii::error("CSRF-FAIL inside validateCsrfTokenInternal (is_string() failed)");
            \Yii::error('$clientSuppliedToken = ' . var_export($clientSuppliedToken, true));
            \Yii::error('$trueToken = ' . var_export($trueToken, true));

            return false;
        }

        $security = Yii::$app->security;

        // moje
        $unmasked_clientSuppliedToken = $security->unmaskToken($clientSuppliedToken);
        $unmasked_trueToken = $security->unmaskToken($trueToken);

        $result = $security->compareString($unmasked_clientSuppliedToken, $unmasked_trueToken);

        if ($result == false)
        {
            \Yii::error('CSRF-FAIL inside validateCsrfTokenInternal ($security->compareString failed)');
            \Yii::error('$clientSuppliedToken = ' . var_export($clientSuppliedToken, true));
            \Yii::error('$trueToken = ' . var_export($trueToken, true));
        }

        return $result;

        //return $security->compareString($security->unmaskToken($clientSuppliedToken), $security->unmaskToken($trueToken));
    }

And this is what we got in the logs:

2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] CSRF-FAIL inside validateCsrfTokenInternal ($security->compareString failed)
2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] $clientSuppliedToken = 'iRo4sGzROQsX06u3KaW4AFD4T72VcitVcl4oF4_f9265SEL5HptmXEDn_dhh9440Frs5i90WewwWH39C97S7Jg=='
2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] $trueToken = 'cjM7M_NEwnsXUmqpJyD3kYPmbGuyG4wYqGZ3SR01GsILRUgBnAW3SSETW9hVTtrb8bADM4Mt633mIRgCbmRyhw=='
2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] CSRF-FAIL inside validateCsrfTokenInternal (is_string() failed)
2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] $clientSuppliedToken = NULL
2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] $trueToken = 'cjM7M_NEwnsXUmqpJyD3kYPmbGuyG4wYqGZ3SR01GsILRUgBnAW3SSETW9hVTtrb8bADM4Mt633mIRgCbmRyhw=='
2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] CSRF-FAIL
2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] $this->enableCsrfValidation = true
2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] CSRF-FAIL inside validateCsrfTokenInternal ($security->compareString failed)
2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] $clientSuppliedToken = 'iRo4sGzROQsX06u3KaW4AFD4T72VcitVcl4oF4_f9265SEL5HptmXEDn_dhh9440Frs5i90WewwWH39C97S7Jg=='
2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] $trueToken = 'cjM7M_NEwnsXUmqpJyD3kYPmbGuyG4wYqGZ3SR01GsILRUgBnAW3SSETW9hVTtrb8bADM4Mt633mIRgCbmRyhw=='
2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] CSRF-FAIL inside validateCsrfTokenInternal (is_string() failed)
2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] $clientSuppliedToken = NULL
2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] $trueToken = 'cjM7M_NEwnsXUmqpJyD3kYPmbGuyG4wYqGZ3SR01GsILRUgBnAW3SSETW9hVTtrb8bADM4Mt633mIRgCbmRyhw=='
2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] $this->request->validateCsrfToken() = false
2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] $this->request->getCsrfToken() = 'cjM7M_NEwnsXUmqpJyD3kYPmbGuyG4wYqGZ3SR01GsILRUgBnAW3SSETW9hVTtrb8bADM4Mt633mIRgCbmRyhw=='
2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] $this->request->getCookies() = yii\web\CookieCollection::__set_state(array(
   'readOnly' => true,
   '_cookies' => 
  array (
  ),
))
2021-02-14 12:21:38 [95.114.106.133][-][-][error][application] $_COOKIE[] = array (
)
2021-02-14 12:21:38 [95.114.106.133][-][-][error][yii\web\HttpException:400] yii\web\BadRequestHttpException: Unable to verify your data submission. in /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/web/Controller.php:217
Stack trace:
#0 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Controller.php(179): yii\web\Controller->beforeAction()
#1 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Module.php(534): yii\base\Controller->runAction()
#2 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/web/Application.php(104): yii\base\Module->runAction()
#3 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Application.php(392): yii\web\Application->handleRequest()
#4 /home/pelock/www/public_html/pelock.com/frontend/web/index.php(20): yii\base\Application->run()
#5 {main}
2021-02-14 12:21:38 [95.114.106.133][-][-][info][application] $_GET = [
    'group' => 'products'
    'name' => 'hash-calculator'
]

$_POST = [
    '_csrf' => 'iRo4sGzROQsX06u3KaW4AFD4T72VcitVcl4oF4_f9265SEL5HptmXEDn_dhh9440Frs5i90WewwWH39C97S7Jg=='
    'HashCalculatorHexForm' => [
        'value' => '8bee3ccad897'
    ]
    'calculate-hash-hex' => ''
]

$_FILES = []

$_COOKIE = []
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] CSRF-FAIL inside validateCsrfTokenInternal ($security->compareString failed)
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] $clientSuppliedToken = 'JUS1EjbYN-yxZ-qhEQualQKxBMiu2unjhNn4Rkil1N8QE_RhdYJbpuQUpcZheN7yNflt-tyYopXjn6wles68iA=='
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] $trueToken = 'pYJISNRWHnzER2PmAQp2cswJ_BCpdAh9HeGBQxfwaxbQ8AUXhhFdJrEQK5JjfgE_tmKwff1AZjtOlcktWaMvfQ=='
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] CSRF-FAIL inside validateCsrfTokenInternal (is_string() failed)
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] $clientSuppliedToken = NULL
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] $trueToken = 'pYJISNRWHnzER2PmAQp2cswJ_BCpdAh9HeGBQxfwaxbQ8AUXhhFdJrEQK5JjfgE_tmKwff1AZjtOlcktWaMvfQ=='
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] CSRF-FAIL
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] $this->enableCsrfValidation = true
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] CSRF-FAIL inside validateCsrfTokenInternal ($security->compareString failed)
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] $clientSuppliedToken = 'JUS1EjbYN-yxZ-qhEQualQKxBMiu2unjhNn4Rkil1N8QE_RhdYJbpuQUpcZheN7yNflt-tyYopXjn6wles68iA=='
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] $trueToken = 'pYJISNRWHnzER2PmAQp2cswJ_BCpdAh9HeGBQxfwaxbQ8AUXhhFdJrEQK5JjfgE_tmKwff1AZjtOlcktWaMvfQ=='
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] CSRF-FAIL inside validateCsrfTokenInternal (is_string() failed)
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] $clientSuppliedToken = NULL
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] $trueToken = 'pYJISNRWHnzER2PmAQp2cswJ_BCpdAh9HeGBQxfwaxbQ8AUXhhFdJrEQK5JjfgE_tmKwff1AZjtOlcktWaMvfQ=='
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] $this->request->validateCsrfToken() = false
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] $this->request->getCsrfToken() = 'pYJISNRWHnzER2PmAQp2cswJ_BCpdAh9HeGBQxfwaxbQ8AUXhhFdJrEQK5JjfgE_tmKwff1AZjtOlcktWaMvfQ=='
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] $this->request->getCookies() = yii\web\CookieCollection::__set_state(array(
   'readOnly' => true,
   '_cookies' => 
  array (
  ),
))
2021-02-14 05:13:57 [180.214.233.91][-][-][error][application] $_COOKIE[] = array (
  'crisp-client%2Fsession%2F022e663c-63c0-43f9-aea2-2d2215e75e4a' => 'session_5adfc5a8-784e-40f0-bc68-dbc00be452f4',
)
2021-02-14 05:13:57 [180.214.233.91][-][-][error][yii\web\HttpException:400] yii\web\BadRequestHttpException: Unable to verify your data submission. in /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/web/Controller.php:217
Stack trace:
#0 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Controller.php(179): yii\web\Controller->beforeAction()
#1 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Module.php(534): yii\base\Controller->runAction()
#2 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/web/Application.php(104): yii\base\Module->runAction()
#3 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Application.php(392): yii\web\Application->handleRequest()
#4 /home/pelock/www/public_html/pelock.com/frontend/web/index.php(20): yii\base\Application->run()
#5 {main}
2021-02-14 05:13:57 [180.214.233.91][-][-][info][application] $_GET = [
    'group' => 'products'
    'name' => 'pubg-mobile-config-encoder-decoder'
]

$_POST = [
    '_csrf' => 'JUS1EjbYN-yxZ-qhEQualQKxBMiu2unjhNn4Rkil1N8QE_RhdYJbpuQUpcZheN7yNflt-tyYopXjn6wles68iA=='
    'PubgDecodeForm' => [
        'input' => '[UserCustom DeviceProfile]

+CVars=0B572C0A1C0B280C1815100D002A1C0D0D10171E444B

+CVars=0B572C0A1C0B2A11181D160E2A0E100D1A114448

+CVars=0B572A11181D160E280C1815100D004448

+CVars=0B5734161B10151C3A16170D1C170D2A1A18151C3F181A0D160B4448

+CVars=0B572C0A1C0B2F0C151218172A1C0D0D10171E4449

+CVars=0B5734161B10151C313D2B44495749

+CVars=0B5734161B10151C572A1A1C171C3A1615160B3F160B14180D44495749

+CVars=0B5734161B10151C573C17181B151C29292B44495749

+CVars=0B572A11181D160E573418013A2A342B1C0A16150C0D1016174448494B4D

+CVars=0B5734180D1C0B101815280C1815100D002A0C091C0B31101E1144495749

+CVars=0B572C0A1C0B313D2B2A1C0D0D10171E4448

+CVars=0B57383A3C2A2A0D00151C4448

+CVars=0B572C0A1C0B342A38382A1C0D0D10171E4449

+CVars=0B573D1C1F180C150D3F1C180D0C0B1C5738170D10381510180A10171E44495749

+CVars=0B5734161B10151C342A383844485749

+CVars=0B57342A38383A160C170D444D5749

+CVars=0B5734180D1C0B101815280C1815100D00351C0F1C154448

+CVars=0B572A11181D160E573A2A345734180134161B10151C3A180A1A181D1C0A444B

+CVars=0B572A11181D160E573D100A0D18171A1C2A1A18151C4449574C

+CVars=0B5734161B10151C573D00171814101A361B131C1A0D2A11181D160E4448

+CVars=0B573D1C090D11361F3F101C151D280C1815100D004449

+CVars=0B572B1C1F0B181A0D101617280C1815100D004449

+CVars=0B572A0D180D101A341C0A1135363D3D100A0D18171A1C2A1A18151C44495741

+CVars=1F161510181E1C5735363D3D100A0D18171A1C2A1A18151C44485749

+CVars=1F161510181E1C5734101735363D4449

+CVars=0B573D1C0D18101534161D1C444B

+CVars=0B573418013817100A160D0B160900444D

+CVars=0B572A0D0B1C181410171E57291616152A10031C444A4949

+CVars=0B573C14100D0D1C0B2A09180E172B180D1C2A1A18151C44485749

+CVars=0B5729180B0D101A151C35363D3B10180A4449

+CVars=0B5734161B10151C370C143D00171814101A291610170D35101E110D0A4448

+CVars=1D1000572A1C0D3D1C1A18153B181210171E2B2D2A10031C301735161B1B004448494B4D

+CVars=0B57292C3B3E2F1C0B0A101617444C

+CVars=0B5734161B10151C2A101409151C2A11181D1C0B4449'
        'output' => ''
    ]
    'decode-button' => ''
]

$_FILES = []

$_COOKIE = [
    'crisp-client%2Fsession%2F022e663c-63c0-43f9-aea2-2d2215e75e4a' => 'session_5adfc5a8-784e-40f0-bc68-dbc00be452f4'
]
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] CSRF-FAIL inside validateCsrfTokenInternal ($security->compareString failed)
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] $clientSuppliedToken = 'JUS1EjbYN-yxZ-qhEQualQKxBMiu2unjhNn4Rkil1N8QE_RhdYJbpuQUpcZheN7yNflt-tyYopXjn6wles68iA=='
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] $trueToken = 'aQjop320Dsy7ZsY81N-oFuQsjNKL83maiamRLcyb0AYceqX4L_NNls4xjki2q99bnkfAv9_HF9za3dlDgsiUbQ=='
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] CSRF-FAIL inside validateCsrfTokenInternal (is_string() failed)
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] $clientSuppliedToken = NULL
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] $trueToken = 'aQjop320Dsy7ZsY81N-oFuQsjNKL83maiamRLcyb0AYceqX4L_NNls4xjki2q99bnkfAv9_HF9za3dlDgsiUbQ=='
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] CSRF-FAIL
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] $this->enableCsrfValidation = true
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] CSRF-FAIL inside validateCsrfTokenInternal ($security->compareString failed)
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] $clientSuppliedToken = 'JUS1EjbYN-yxZ-qhEQualQKxBMiu2unjhNn4Rkil1N8QE_RhdYJbpuQUpcZheN7yNflt-tyYopXjn6wles68iA=='
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] $trueToken = 'aQjop320Dsy7ZsY81N-oFuQsjNKL83maiamRLcyb0AYceqX4L_NNls4xjki2q99bnkfAv9_HF9za3dlDgsiUbQ=='
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] CSRF-FAIL inside validateCsrfTokenInternal (is_string() failed)
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] $clientSuppliedToken = NULL
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] $trueToken = 'aQjop320Dsy7ZsY81N-oFuQsjNKL83maiamRLcyb0AYceqX4L_NNls4xjki2q99bnkfAv9_HF9za3dlDgsiUbQ=='
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] $this->request->validateCsrfToken() = false
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] $this->request->getCsrfToken() = 'aQjop320Dsy7ZsY81N-oFuQsjNKL83maiamRLcyb0AYceqX4L_NNls4xjki2q99bnkfAv9_HF9za3dlDgsiUbQ=='
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] $this->request->getCookies() = yii\web\CookieCollection::__set_state(array(
   'readOnly' => true,
   '_cookies' => 
  array (
    '_csrf' => 
    yii\web\Cookie::__set_state(array(
       'name' => '_csrf',
       'value' => 'urM_RGCZuWHtbtwMzkLmT4nFStHnNSDk',
       'domain' => '',
       'expire' => NULL,
       'path' => '/',
       'secure' => false,
       'httpOnly' => true,
       'sameSite' => NULL,
    )),
  ),
))
2021-02-14 05:14:03 [180.214.233.91][-][-][error][application] $_COOKIE[] = array (
  'crisp-client%2Fsession%2F022e663c-63c0-43f9-aea2-2d2215e75e4a' => 'session_5adfc5a8-784e-40f0-bc68-dbc00be452f4',
  '_csrf' => 'eb41833be72a2b0620cc91cc46805ecd0bd53f6c4526a3517661de521c4459f6a:2:{i:0;s:5:"_csrf";i:1;s:32:"urM_RGCZuWHtbtwMzkLmT4nFStHnNSDk";}',
)
2021-02-14 05:14:03 [180.214.233.91][-][-][error][yii\web\HttpException:400] yii\web\BadRequestHttpException: Unable to verify your data submission. in /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/web/Controller.php:217
Stack trace:
#0 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Controller.php(179): yii\web\Controller->beforeAction()
#1 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Module.php(534): yii\base\Controller->runAction()
#2 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/web/Application.php(104): yii\base\Module->runAction()
#3 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Application.php(392): yii\web\Application->handleRequest()
#4 /home/pelock/www/public_html/pelock.com/frontend/web/index.php(20): yii\base\Application->run()
#5 {main}
2021-02-14 05:14:03 [180.214.233.91][-][-][info][application] $_GET = [
    'group' => 'products'
    'name' => 'pubg-mobile-config-encoder-decoder'
]

$_POST = [
    '_csrf' => 'JUS1EjbYN-yxZ-qhEQualQKxBMiu2unjhNn4Rkil1N8QE_RhdYJbpuQUpcZheN7yNflt-tyYopXjn6wles68iA=='
    'PubgDecodeForm' => [
        'input' => '[UserCustom DeviceProfile]

+CVars=0B572C0A1C0B280C1815100D002A1C0D0D10171E444B

+CVars=0B572C0A1C0B2A11181D160E2A0E100D1A114448

+CVars=0B572A11181D160E280C1815100D004448

+CVars=0B5734161B10151C3A16170D1C170D2A1A18151C3F181A0D160B4448

+CVars=0B572C0A1C0B2F0C151218172A1C0D0D10171E4449

+CVars=0B5734161B10151C313D2B44495749

+CVars=0B5734161B10151C572A1A1C171C3A1615160B3F160B14180D44495749

+CVars=0B5734161B10151C573C17181B151C29292B44495749

+CVars=0B572A11181D160E573418013A2A342B1C0A16150C0D1016174448494B4D

+CVars=0B5734180D1C0B101815280C1815100D002A0C091C0B31101E1144495749

+CVars=0B572C0A1C0B313D2B2A1C0D0D10171E4448

+CVars=0B57383A3C2A2A0D00151C4448

+CVars=0B572C0A1C0B342A38382A1C0D0D10171E4449

+CVars=0B573D1C1F180C150D3F1C180D0C0B1C5738170D10381510180A10171E44495749

+CVars=0B5734161B10151C342A383844485749

+CVars=0B57342A38383A160C170D444D5749

+CVars=0B5734180D1C0B101815280C1815100D00351C0F1C154448

+CVars=0B572A11181D160E573A2A345734180134161B10151C3A180A1A181D1C0A444B

+CVars=0B572A11181D160E573D100A0D18171A1C2A1A18151C4449574C

+CVars=0B5734161B10151C573D00171814101A361B131C1A0D2A11181D160E4448

+CVars=0B573D1C090D11361F3F101C151D280C1815100D004449

+CVars=0B572B1C1F0B181A0D101617280C1815100D004449

+CVars=0B572A0D180D101A341C0A1135363D3D100A0D18171A1C2A1A18151C44495741

+CVars=1F161510181E1C5735363D3D100A0D18171A1C2A1A18151C44485749

+CVars=1F161510181E1C5734101735363D4449

+CVars=0B573D1C0D18101534161D1C444B

+CVars=0B573418013817100A160D0B160900444D

+CVars=0B572A0D0B1C181410171E57291616152A10031C444A4949

+CVars=0B573C14100D0D1C0B2A09180E172B180D1C2A1A18151C44485749

+CVars=0B5729180B0D101A151C35363D3B10180A4449

+CVars=0B5734161B10151C370C143D00171814101A291610170D35101E110D0A4448

+CVars=1D1000572A1C0D3D1C1A18153B181210171E2B2D2A10031C301735161B1B004448494B4D

+CVars=0B57292C3B3E2F1C0B0A101617444C

+CVars=0B5734161B10151C2A101409151C2A11181D1C0B4449'
        'output' => ''
    ]
    'decode-button' => ''
]

$_FILES = []

$_COOKIE = [
    'crisp-client%2Fsession%2F022e663c-63c0-43f9-aea2-2d2215e75e4a' => 'session_5adfc5a8-784e-40f0-bc68-dbc00be452f4'
    '_csrf' => 'eb41833be72a2b0620cc91cc46805ecd0bd53f6c4526a3517661de521c4459f6a:2:{i:0;s:5:\"_csrf\";i:1;s:32:\"urM_RGCZuWHtbtwMzkLmT4nFStHnNSDk\";}'
]
PELock commented 3 years ago

Common thing -> multiple forms.

My controller for the hash calculator

    public function actionHashCalculator($group, $name)
    {
        // usage counts
        $this->view->params['HashCalculatorCounter'] = Integers::findByDescription('hash_calculator');

        // create a new form model
        $model_string = new HashCalculatorForm();
        $model_hex = new HashCalculatorHexForm();
        $model_file = new HashCalculatorFileForm();

        $bHashDone = false;

        // was it posted?
        if (Yii::$app->request->isPost)
        {
            if ($model_string->load(Yii::$app->request->post()))
            {
                $result = $model_string->hashCalculate();
                $bHashDone = true;
            }
            else if ($model_hex->load(Yii::$app->request->post()))
            {
                $result = $model_hex->hashCalculate();
                $bHashDone = true;
            }
            else if ($model_file->load(Yii::$app->request->post()))
            {
                $result = $model_file->hashCalculate();
                $bHashDone = true;
            }
        }

        if ($bHashDone == true)
        {
            if (!empty($result))
            {
                $this->view->params['result'] = $result;

                Yii::$app->session->setFlash('EventFormSubmitted');

                return $this->renderByLang($group . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . 'index', [ 'model_string' => $model_string, 'model_hex' => $model_hex, 'model_file' => $model_file ] );
            }

            return $this->refresh();
        }

        return $this->renderByLang($group . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . 'index', [ 'model_string' => $model_string, 'model_hex' => $model_hex, 'model_file' => $model_file ] );
    }
PELock commented 3 years ago

Isn't it that Yii::$app->request->post() can generate different CSRF token? Would make some sense... Isn't it some event attached to this method that triggers csrf token re-generation?

PELock commented 3 years ago

I'm changing my controller code to read post params only one time:

    public function actionHashCalculator($group, $name)
    {
        // usage counts
        $this->view->params['HashCalculatorCounter'] = Integers::findByDescription('hash_calculator');

        // create a new form model
        $model_string = new HashCalculatorForm();
        $model_hex = new HashCalculatorHexForm();
        $model_file = new HashCalculatorFileForm();

        $bHashDone = false;

        // was it posted?
        if (Yii::$app->request->isPost)
        {
            $post_params = Yii::$app->request->post();

            if ($model_string->load($post_params))
            {
                $result = $model_string->hashCalculate();
                $bHashDone = true;
            }
            else if ($model_hex->load($post_params))
            {
                $result = $model_hex->hashCalculate();
                $bHashDone = true;
            }
            else if ($model_file->load($post_params))
            {
                $result = $model_file->hashCalculate();
                $bHashDone = true;
            }
        }

        if ($bHashDone == true)
        {
            if (!empty($result))
            {
                $this->view->params['result'] = $result;

                Yii::$app->session->setFlash('EventFormSubmitted');

                return $this->renderByLang($group . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . 'index', [ 'model_string' => $model_string, 'model_hex' => $model_hex, 'model_file' => $model_file ] );
            }

            return $this->refresh();
        }

        return $this->renderByLang($group . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . 'index', [ 'model_string' => $model_string, 'model_hex' => $model_hex, 'model_file' => $model_file ] );
    }

and see if it will trigger this error.

samdark commented 3 years ago

The fact that token supplied looks different doesn't necessary means that CSRF check would fail. We use token masking.

samdark commented 3 years ago

Common thing -> multiple forms.

Do you mean that if only a single form is there, it works well and when there are multiple it fails?

PELock commented 3 years ago

So far, so good, not a single error (I have made this change to those 2 routes). I will update you in a few hours.

I've been looking into this request post method, at one point it calls:

    /**
     * Returns the raw HTTP request body.
     * @return string the request body
     */
    public function getRawBody()
    {
        if ($this->_rawBody === null) {
            $this->_rawBody = file_get_contents('php://input');
        }

        return $this->_rawBody;
    }

Isn't it the issue? Just wildguessing ;)

samdark commented 3 years ago

I have made this change to those 2 routes

Do you mean leaving only a single form or changing Yii's code? If later, which code did you change and how?

PELock commented 3 years ago

I left my logging code in Yii2 components and when I handle the form I read $post_params = Yii::$app->request->post(); only one time (not 3 time for 3 diff forms). Like this, I have also added a form name to distinguish each one (I would love this feature be in the default implementation [public form name as a property or a setter], for example when I have 3 forms of the same model):

    public function actionHashCalculator($group, $name)
    {
        // usage counts
        $this->view->params['HashCalculatorCounter'] = Integers::findByDescription('hash_calculator');

        // create a new form model
        $model_string = new HashCalculatorForm();
        $model_string->_formName = "HashCalculatorForm";

        $model_hex = new HashCalculatorHexForm();
        $model_hex->_formName = "HashCalculatorHexForm";

        $model_file = new HashCalculatorFileForm();
        $model_file->_formName = "HashCalculatorFileForm";

        $bHashDone = false;

        // was it posted?
        if (Yii::$app->request->isPost)
        {
            $post_params = Yii::$app->request->post();

            if ($model_string->load($post_params, $model_string->_formName))
            {
                $result = $model_string->hashCalculate();
                $bHashDone = true;
            }
            else if ($model_hex->load($post_params, $model_hex->_formName))
            {
                $result = $model_hex->hashCalculate();
                $bHashDone = true;
            }
            else if ($model_file->load($post_params, $model_file->_formName))
            {
                $result = $model_file->hashCalculate();
                $bHashDone = true;
            }
        }

        if ($bHashDone == true)
        {
            if (!empty($result))
            {
                $this->view->params['result'] = $result;

                Yii::$app->session->setFlash('EventFormSubmitted');

                return $this->renderByLang($group . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . 'index', [ 'model_string' => $model_string, 'model_hex' => $model_hex, 'model_file' => $model_file ] );
            }

            return $this->refresh();
        }

        return $this->renderByLang($group . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . 'index', [ 'model_string' => $model_string, 'model_hex' => $model_hex, 'model_file' => $model_file ] );
    }

Model change:

class HashCalculatorForm extends Model
{
...
    public $_formName;

    public function formName()
    {
        return $this->_formName;
    }
...
PELock commented 3 years ago

Nope, it's not it, still the same error:

2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] CSRF-FAIL inside validateCsrfTokenInternal ($security->compareString failed)
2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] $clientSuppliedToken = 'wk8EiUWgkTqglh2WVv6hTAEizieF3cuqK8Nlo2YJuHCDJU7kCv_ITPfGa8A-pOIeQ0yZft-Vnu9d9SD0K0XUSQ=='
2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] $trueToken = 'OVIxI-j2VumkHcxC6yq8XgE6I7WkVqk9zYzIqGmvsrt2JnVIsbsbjux4uC7dXI0VUWl21McZy1X5xaaYAuvHiA=='
2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] CSRF-FAIL inside validateCsrfTokenInternal (is_string() failed)
2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] $clientSuppliedToken = NULL
2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] $trueToken = 'OVIxI-j2VumkHcxC6yq8XgE6I7WkVqk9zYzIqGmvsrt2JnVIsbsbjux4uC7dXI0VUWl21McZy1X5xaaYAuvHiA=='
2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] CSRF-FAIL
2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] $this->enableCsrfValidation = true
2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] CSRF-FAIL inside validateCsrfTokenInternal ($security->compareString failed)
2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] $clientSuppliedToken = 'wk8EiUWgkTqglh2WVv6hTAEizieF3cuqK8Nlo2YJuHCDJU7kCv_ITPfGa8A-pOIeQ0yZft-Vnu9d9SD0K0XUSQ=='
2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] $trueToken = 'OVIxI-j2VumkHcxC6yq8XgE6I7WkVqk9zYzIqGmvsrt2JnVIsbsbjux4uC7dXI0VUWl21McZy1X5xaaYAuvHiA=='
2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] CSRF-FAIL inside validateCsrfTokenInternal (is_string() failed)
2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] $clientSuppliedToken = NULL
2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] $trueToken = 'OVIxI-j2VumkHcxC6yq8XgE6I7WkVqk9zYzIqGmvsrt2JnVIsbsbjux4uC7dXI0VUWl21McZy1X5xaaYAuvHiA=='
2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] $this->request->validateCsrfToken() = false
2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] $this->request->getCsrfToken() = 'OVIxI-j2VumkHcxC6yq8XgE6I7WkVqk9zYzIqGmvsrt2JnVIsbsbjux4uC7dXI0VUWl21McZy1X5xaaYAuvHiA=='
2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] $this->request->getCookies() = yii\web\CookieCollection::__set_state(array(
   'readOnly' => true,
   '_cookies' => 
  array (
  ),
))
2021-02-14 20:50:02 [182.2.136.13][-][-][error][application] $_COOKIE[] = array (
  'crisp-client%2Fsession%2F022e663c-63c0-43f9-aea2-2d2215e75e4a' => 'session_6fbffc93-aed5-4d8e-9db7-48a5e1873e47',
)
2021-02-14 20:50:02 [182.2.136.13][-][-][error][yii\web\HttpException:400] yii\web\BadRequestHttpException: Unable to verify your data submission. in /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/web/Controller.php:217
Stack trace:
#0 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Controller.php(179): yii\web\Controller->beforeAction()
#1 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Module.php(534): yii\base\Controller->runAction()
#2 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/web/Application.php(104): yii\base\Module->runAction()
#3 /home/pelock/www/public_html/pelock.com/vendor/yiisoft/yii2/base/Application.php(392): yii\web\Application->handleRequest()
#4 /home/pelock/www/public_html/pelock.com/frontend/web/index.php(20): yii\base\Application->run()
#5 {main}
2021-02-14 20:50:02 [182.2.136.13][-][-][info][application] $_GET = [
    'group' => 'products'
    'name' => 'pubg-mobile-config-encoder-decoder'
]

$_POST = [
    '_csrf' => 'wk8EiUWgkTqglh2WVv6hTAEizieF3cuqK8Nlo2YJuHCDJU7kCv_ITPfGa8A-pOIeQ0yZft-Vnu9d9SD0K0XUSQ=='
    'PubgEncodeForm' => [
        'input' => '[UserCustom DeviceProfile]
+CVars=r.UserQualitySetting=0
+CVars=r.UserShadowSwitch=0
+CVars=r.ShadowQuality=0
+CVars=r.MobileContentScaleFactor=1.0
+CVars=r.UserVulkanSetting=1
+CVars=r.MobileHDR=0.0
+CVars=r.Mobile.SceneColorFormat=0.0
+CVars=r.Mobile.EnablePPR=0.0
+CVars=r.Shadow.MaxCSMResolution=1024
+CVars=r.MaterialQualitySuperHigh=0.0
+CVars=r.UserHDRSetting=2
+CVars=r.ACESStyle=1
+CVars=r.UserMSAASetting=0
+CVars=r.DefaultFeature.AntiAliasing=0.0
+CVars=r.MobileMSAA=0.0
+CVars=r.MSAACount=1.0
+CVars=r.StaticMeshLODDistanceScale=0.8
+CVars=foliage.LODDistanceScale=1
+CVars=r.ParticleLODBias=4
+CVars=r.EmitterSpawnRateScale=1
+CVars=r.DetailMode=2
+CVars=r.Shadow.CSM.MaxMobileCascades=2
+CVars=r.Shadow.DistanceScale=0.5
+CVars=r.MaxAnisotropy=4
+CVars=r.MaterialQualityLevel=1
+CVars=r.Mobile.DynamicObjectShadow=1
+CVars=r.DepthOfFieldQuality=0
+CVars=r.RefractionQuality=0
+CVars=foliage.MinLOD=0
+CVars=r.Streaming.PoolSize=400
+CVars=r.MobileNumDynamicPointLights=1
+CVars=r.PUBGVersion=5
+CVars=r.MobileSimpleShader=0
+CVars=fx.MaxCPUParticlesPerEmitter 1000'
        'output' => ''
    ]
    'encode-button' => ''
]

$_FILES = []

$_COOKIE = [
    'crisp-client%2Fsession%2F022e663c-63c0-43f9-aea2-2d2215e75e4a' => 'session_6fbffc93-aed5-4d8e-9db7-48a5e1873e47'
]

This time csrf cookie wasn't even there... What can I do to investigate it further?

samdark commented 3 years ago

These are two entirely different situations:

  1. No cookie. Framework reacts alright to this case so the issue is lack of cookie. It may be valid case when a bot crawls the website and saves no cookies or user turned cookies off. I see that in your case you have domain set to empty string for your cookies. Usually that's totally fine but you may try setting it to domain prefixed by . explicitly.
  2. CSRF token isn't correct. In this case it could be valid blocking or submitting too many POSTs at once.
PELock commented 3 years ago
  1. That might happen but the form data is valid, why would bot POST actual data to the form?
  2. So you're saying they clicked the submit button multiple times?
samdark commented 3 years ago
  1. If it doesn't look like a spam then yes, likely that's valid user.
  2. No idea. Try it.
PELock commented 3 years ago

Maybe I should store CSRF in the session instead of cookies?

bizley commented 3 years ago

This is what I suggested already.

bizley commented 3 years ago

Closing since we cannot provide a way to reproduce the problem. If anything new develops please let us know.

nareka88 commented 3 years ago

1) backend/config/main-local.php 'components' => [ 'request' => [ //!!! insert a secret key in the following (if it is empty) - this is required by cookie validation 'cookieValidationKey' => 'unique key here', 'csrfParam' => '_csrf-backend', **'csrfCookie' => [ 'httpOnly' => true, 'path' => '/admin/', ],** ],

2) frontend/config/main-local.php 'components' => [ 'request' => [ //!!! insert a secret key in the following (if it is empty) - this is required by cookie validation 'cookieValidationKey' => 'unique key here', 'csrfParam' => '_csrf-frontend', **'csrfCookie' => [ 'httpOnly' => true, 'path' => '/', ],** ],

for me solved without disabling CSRF. good luck

@bizley @samdark

PELock commented 3 years ago

My config looks like (advanced template):

        'request' => [
            // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
            'cookieValidationKey' => 'XXXXXXXXXXXXXXXXXXXXXX',

            'csrfCookie' => [
                'httpOnly' => true,
                'secure' => true,
                'sameSite' => yii\web\Cookie::SAME_SITE_STRICT
            ],

Does it mean I was missing csrfParam field???

bizley commented 3 years ago

Well, no, by default it's _csrf and changing it should not affect the normal behavior but... since it looks like we tried everything we could think of trying to fix the problem, we can try this as well. Let us know @PELock

PELock commented 3 years ago

I don't think the name of the csrf token has anything to do with it, I'm trying this one:

        'request' => [
            // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
            'cookieValidationKey' => 'XXXXXXXXXXXXXXXXXXXXXXXXXXX',

            'csrfParam' => '_csrf-frontend',

            'csrfCookie' => [
                'httpOnly' => true,
                //'secure' => true,
                //'sameSite' => yii\web\Cookie::SAME_SITE_STRICT
            ],
        ],

So I left httpOnly and commented out secure options. Logs cleared, new version pushed to the server. Waiting for results ;)

PELock commented 3 years ago

I have a question, I've been looking at the advanced template and its config looks different, what is the official, recommended config for this CSRF & Sessions? Maybe I'm doing something I shouldn't do in my configuration?

bizley commented 3 years ago

It all looks ok. If you use https definitely you should set secure to true, sameSite lax or strict as well.