Yii2: csrf

Created on 4 Jun 2017  ·  50Comments  ·  Source: yiisoft/yii2

What steps will reproduce the problem?

Здравствуйте, версия yii 2.0.11.2 передаю ajax запрос:
$.ajax({
type: "POST",
url: '/test',
dataType: 'json',
data: {
'_csrf': $('meta[name="csrf-token"]').attr('content'),
'test': 5
},
success: function (server) {
console.log(server);
}
});
не во всех браузерах он работает например в опере ответ от сервера (400 (Bad Request))

What is the expected result?

Сервер должен ответить без ошибок.

What do you get instead?

Ответ сервера.

Additional info

Как я понял проблема в _csrf не во всех браузерах он работает при передаче через ajax
| Q | A
| ---------------- | ---
| Yii version | 2.0.11.2?
| PHP version | 5.5.31
| Operating system | Linux rt.ru 2.6.32-042stab112.15 #1 SMP Tue Oct 20 17:22:56 MSK 2015 x86_64

question

Most helpful comment

да, сделаю

All 50 comments

500 — это точно не CSRF.

Thank you for your question.
In order for this issue tracker to be effective, it should only contain bug reports and feature requests.

We advise you to use our community driven resources:

If you are confident that there is a bug in the framework, feel free to provide information on how to reproduce it. This issue will be closed for now.

_This is an automated comment, triggered by adding the label question._

так же такой ответ приходит (400 (Bad Request)) но если я отключу CSRF то ответ от сервера корректный приходит

@sapsxxxil do you get a 400 or 500 error? While 500 seem to be not related to the CSRF the 400 may be.

This is probably related to the https://github.com/yiisoft/yii2/issues/13726. I experience this problem too, still can not reproduce it reliably. I can not determine specific conditions when and why it occurs.

ошибка 400, да похоже, что связано #13726 она у меня возникает только если я передаю через ajax и включая csrf если отключу csrf то работает

@sapsxxxil do you send a CSRF token while making an AJAX request?

да:
$.ajax({
type: "POST",
url: '/test',
dataType: 'json',
data: {
'_csrf': $('meta[name="csrf-token"]').attr('content'),
'test': 5
},
success: function (server) {
console.log(server);
}
});

@sapsxxxil _csrf part is incorrect in a generic case. Token parameter name is defined in csrf-param meta tag.

нет я беру токен из тега csrf-token теги:

<meta name="csrf-param" content="_csrf"> <meta name="csrf-token" content="SVVZR0tfemMrOywkfAA5NS8XMgIUay0hI20MC3oMQg0QJwAoKhwAMQ==">

csrf-param пустой на странице

@sapsxxxil what do you mean by

csrf-param is empty on the page

It seems to be equal _csrf from what you post.

имел виду, что токен я беру отсюда

@sapsxxxil I can not reproduce it reliably to debug it. It happens like once a day for me. If you can reproduce it, could you please debug this method? Which particular condition fails and why?

@sapsxxxil And why do you add this?

data: {
'_csrf': $('meta[name="csrf-token"]').attr('content')
}

Just wondering, because if layout has <?= Html::csrfMetaTags(); ?> then the token is automatically send CSRF token for all AJAX requests.

@Blacknife the patch which added this feature was released just a couple of month ago in 2.0.11. People may still use previous versions of a framework or do not know about this feature. Also yii.js may not be present in an application all together as it's not a mandatory dependency.

@Kolyunya do not look at commits, the code has the property of changing https://github.com/yiisoft/yii2/issues/1367#issuecomment-29558436

записи из лога:
[error][yii\web\HttpException:400] exception 'yii\web\BadRequestHttpException' with message 'Unable to verify your data submission.' in /vendor/yiisoft/yii2/web/Controller.php:166
Stack trace:

0 /vendor/yiisoft/yii2/base/Controller.php(154): yii\web\Controller->beforeAction(Object(yii\base\InlineAction))

1 /vendor/yiisoft/yii2/base/Module.php(523): yii\base\Controller->runAction('login-input', Array)

2 /vendor/yiisoft/yii2/web/Application.php(102): yii\base\Module->runAction('authorization/l...', Array)

3 /vendor/yiisoft/yii2/base/Application.php(380): yii\web\Application->handleRequest(Object(yii\web\Request))

4 /web/index.php(12): yii\base\Application->run()

5 {main}

2017-06-07 01:16:03 [2.94.73.131][-][-][info][application] $_POST = [
'login' => ''
'password' => ''
]

$_COOKIE = [
'_ym_uid' => '1487534187430350632'
]

при загрузке обычной странице где нет ошибке присутствует такая запись:
[info][application] $_COOKIE = [
'_ym_uid' => '1466541869846602052'
'_ga' => 'GA1.2.549868944.1471899701'
'_csrf' => '20f40abd3db383573eb6a4a8d645c3b4cd5bdd4356fea6db2fe4bd6e47b7554da:2:{i:0;s:5:\"_csrf\";i:1;s:32:\"bnuc7_CVfBkE_4WBj8UL1S8nYrYoaCzR\";}'
'login' => '997a1926772fd3f1dc4617810ffd6f156f31e48729b2ca0e8d5b4d8e5f1a07d2a:2:{i:0;s:5:\"login\";i:1;a:1:{s:7:\"user_id\";i:15;}}'
]

но при передаче через ajax с включенным csrf в опере таких данных нет

я об этой записи: '_csrf' => '20f40abd3db383573eb6a4a8d645c3b4cd5bdd4356fea6db2fe4bd6e47b7554da:2:{i:0;s:5:"_csrf";i:1;s:32:"bnuc7_CVfBkE_4WBj8UL1S8nYrYoaCzR";}'

Значит на странице, с которой отправляется запрос, не выставляется токен.

токен точно есть в мета теге, посмотрите http://garant.shopotom24.ru я его даже в консоль вывожу на js, при нажатие на кнопку (Войти), просто нажмите на кнопку (Войти) и посмотрите, что в консоли браузера будет написано

@sapsxxxil I didn't receive neither a CSRF nor a session cookie. I may be mistaken but one of these is required to obtain the correct token on a server side.

если нужно вот версия браузера опера в котором это происходит Opera 45.0

@sapsxxxil it happens in latest Chromium for me.

@Kolyunya reproduced?

@samdark I'm just saying that the page @sapsxxxil posted a link to does not send a CSRF cookie for me. I think that may be the source of the problem.

могу экран показать если нужно

@sapsxxxil I would suggest you to debug why your application does not send a CSRF or session (if you store tokens in session) cookie. This seems to be the source of your problem.

Yes, that is definitely the reason. Since we have no way to reproduce that we can't fix it :(

@sapsxxxil do you receive a _csrf cookie in any browser on that page? I checked three different browsers and didn't receive that cookie in any of them.

в opere - не работает, в Chrome - работает, в остальных браузерах то работает то нет. ОШИБКА эта есть и она все еще остается

@sapsxxxil cookies do not work in any browser on page http://garant.shopotom24.ru/ , server just does not send them for some reason

Check for yourself, you will get cookies only if you go to any page for example

http://garant.shopotom24.ru/basic/web/index.php/debug/default/view?panel=assets&tag=5937d763e286f

@sapsxxxil do you receive a _csrf cookie in Chrome when you clear them and go to http://garant.shopotom24.ru?

да в Chrome я получаю cookie

как может сервер не правильно работать если в некоторых браузерах то работает то нет

@sapsxxxil have you tried clearing cookies completely for that domain and going to http://garant.shopotom24.ru/ in Chrome? Do you receive cookies on that particular page?

@sapsxxxil i checked all the browsers have with this page http://garant.shopotom24.ru, and i get cookies only when i go to the debugger page

including Chrome

да если в Chrome очистить все куки то тоже не работает

@sapsxxxil then it seems to be the backend application issue and it's not browser-related.

на сервере пустой метод public function actionLoginInput() { echo json_encode(['login' => true]); }

@sapsxxxil this may be a configuration issue.

configuration:
`

$params = require(__DIR__ . '/params.php');

$config = [
'id' => 'basic',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'components' => [
'request' => [
// !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
'cookieValidationKey' => 'IMlDD10-6QkHGJhtqv5CUMrWuHYLeYnm',
'baseUrl'=> '',
//'enableCsrfValidation' => false, //отключили Csrf
],
'cache' => [
'class' => 'yii\caching\FileCache',
],
'user' => [
'identityClass' => 'app\models\User',
'enableAutoLogin' => true,
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
// send all mails to a file by default. You have to set
// 'useFileTransport' to false and configure a transport
// for the mailer to send real emails.
'useFileTransport' => true,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'db' => require(__DIR__ . '/db.php'),

    'urlManager' => [
        'enablePrettyUrl' => true,
       // 'showScriptName' => false,
        'rules' => [
            'authorization/login-input' => 'authorization/login-input',
            [
                'class' => 'app\components\MyUrlRule',
            ],
        ],
    ],

],
'params' => $params,

];

if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
'class' => 'yii\debug\Module',
'allowedIPs' => ['...'],
];

$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
    'class' => 'yii\gii\Module',
    'allowedIPs' => ['*.*.*.*'],
];

}

return $config;
`

@sapsxxxil can you publish an minimal app-basic-based application which reproduces the problem?

да, сделаю

установил версию: php composer.phar create-project yiisoft/yii2-app-basic basic 2.0.12 перешел по адресу http://code-geek.shopotom24.ru/basic/web/index.php ошибка, не может найти папку vendor/bower но есть папка vendor/bower-asset

@sapsxxxil установи composer-asset-plugin командой
composer global require "fxp/composer-asset-plugin:^1.3.1"
и тогда bower и composer будут знать друг о дружке, а сейчас достаточно папку bower-asset переименовать в bower

http://www.yiiframework.com/doc-2.0/guide-start-installation.html#installing-from-composer

в basic работает тогда снимается вопрос

браузер - opera 50.0
версия Yii - 2.0.13.1
В опере сохраняться открытые вкладки при ее запуске.
Если открыть проект на Yii2 в опере, потом закрыть браузер и снова открыть то при
отправление AJAX запрос ошибка (400 (Bad Request)), если обновить эту вкладку то все работает, также если отключить csrf то работает.
В остальных браузерах при подобных действиях все работает

Особенности браузера... Он так себя вести не должен, но ведёт...

Was this page helpful?
0 / 5 - 0 ratings

Related issues

deecode picture deecode  ·  50Comments

spiritdead picture spiritdead  ·  67Comments

njasm picture njasm  ·  44Comments

schmunk42 picture schmunk42  ·  47Comments

vercotux picture vercotux  ·  47Comments