ÏȻһ·ùÁ÷³ÌͼÀíÀí˼·£º

1. ÎÊÌâÊÇÕâÑùµÄ£º
½ñÌìÔÚ´¦ÀíÒ»¸öÕâÑùµÄÐèÇó£¬ ÔÚ app\controllers\LoginController.phpÖж¨ÒåÁËindex·½·¨À´´¦ÀíµÇ¼£¨Ö÷ÒªÊÇÓÃÓÚ·ÇWebÒ³ÃæµÇ¼£¬±ÈÈçCurl
-X POST http://api/login£©£º
½á¹ûÄØ£¬ ÎÞÂÛÊÇÓòâÊÔ¹¤¾ßPOSTMAN»¹ÊÇÓÃÃüÁîÐÐCURLÇëÇó×ÜÊÇ»áµÃµ½ http400:Bad RequestµÄ´íÎó£»¶øÈç¹ûÓÃWebÍøÒ³·½Ê½GET·ÃÎÊ(È¥³ýverbFilterµÄPOSTÏÞÖÆ)£¬ÊÇÕý³£µÄ
ͨ¹ýÌû×ÓÏÂÃæµÄÌû×ÓÕÒµ½ÁËÎÊÌâµÄËùÔÚ£¬ÊÇCSRFÑéÖ¤µÄÔÒò£»
ÒòΪWebÍøÒ³·ÃÎʵÄʱºòform±íµ¥ÖлáÓжÔÓ¦µÄÒ»¸öÒþ²Øinput:_csrf½øÐÐÁËÑéÖ¤²Å¿ÉÒÔÕý³£½øÐзÃÎÊ£»
¶ø·ÇÍøÒ³·ÃÎÊ·½Ê½£¨²»Í¨¹ýWeb±íµ¥£©ÊÇÎÞ·¨Í¨¹ýcsrfÑéÖ¤µÄ¡£
¶øCURL·ÃÎÊ·½Ê½¶¼Ã»ÓÐÓõ½cookie£¬ ¹ÊÎÒÈÏΪûÓбØÒªÔÚÕâÀï·À·¶csrf¹¥»÷£¬ÔÝʱÓÃÏÂÃæµÄ°ì·¨½«Æä½ûÓá£
class Controller extends \yii\base\Controller { /** * @var boolean whether to enable CSRF validation for the actions in this controller. * CSRF validation is enabled only when both this property and [[Request::enableCsrfValidation]] are true. */ public $enableCsrfValidation = false; <- set this to false |
2. ³Ã»úÀ´Ñо¿Ï Yii2 µÄ CSRF ·À·¶»úÖÆ
ʲôÊÇ CSRF ¹¥»÷£¿
¼òµ¥Ëµ£¬ ¹¥»÷ÕßµÁÓÃÁËÄãµÄÉí·Ý£¬ÒÔÄãµÄÃûÒå·¢ËͶñÒâÇëÇó¡£
×îÓÐЧµØÒ»¸ö·½·¨ÔÀíÊÇÕâÑùµÄ£º
Cookie Hashing£¬ È÷þÎñÆ÷·¢Ë͸ø¿Í»§¶ËµÄËùÓÐ±íµ¥Öж¼±êʾһ¸öËæ»úÖµ_csrf£¬²¢Í¬Ê±ÔÚ¿Í»§¶ËµÄCOOKIEÖб£´æÒ»¸öÏà¹ØÁªµÄtoken;
ÑéÖ¤µÄʱºò£¬·þÎñ¶Ëÿ´Î¶Ô½ÓÊÕµ½µÄÇëÇó_POST()¹ýÀ´µÄÒ»¸öinput
hidden _csrf¸ú¿Í»§¶ËµÄCOOKIEÖеÄtoken½øÐжÔÕÕÑéÖ¤
¹¥»÷Õß¹¥»÷µÄÔÀíÊÇÀûÓÃÁ˿ͻ§¶ËµÄCOOKIE£¬µ«Êǹ¥»÷ÕßÊǵò»µ½COOKIE¾ßÌåµÄÄÚÈݵģ¬ËûÖ»ÊÇÀûÓÃ(ÕâÀïÅ׿ªXSS¹¥»÷µÄ¿ÉÄÜÐÔ,ÓÉÓÚÓû§µÄCookieºÜÈÝÒ×ÓÉÓÚÍøÕ¾µÄXSS©¶´¶ø±»µÁÈ¡£¬Õâ¾ÍÁíÍâµÄ1%¡£Ò»°ãµÄ¹¥»÷Õß¿´µ½ÓÐÐèÒªËãHashÖµ£¬»ù±¾¶¼»á·ÅÆúÁË)£»ËùÒÔ¹¥»÷Õßû·¨ÔÚ¹¥»÷URLÖмÓÈëtoken£¬ÕâÑù¾ÍÎÞ·¨Í¨¹ýÑéÖ¤¡£
Õâ¿ÉÄÜÊÇ×î¼òµ¥µÄ½â¾ö·½°¸ÁË£¬ÒòΪ¹¥»÷Õß²»ÄÜ»ñµÃµÚÈý·½µÄCookie(ÀíÂÛÉÏ)£¬ËùÒÔ±íµ¥ÖеÄÊý¾ÝÒ²¾Í¹¹Ôìʧ°ÜÁË:>
À´¿´¿´£ºYii2ÊDz»ÊÇÕâô¸ÉµÄ¡£
3. ´ÓÍâµ½ÄÚ̽¾¿
YiiÎĵµÖÐÓÐÕâôһ¶Î»°ÊÇ¶ÔÆäCSRF·À·¶»úÖÆµÄ¸ÅÊö£º
When CSRF validation is enabled, forms submitted to an Yii Web application must be originated * from the same application. If not, a 400 HTTP exception will be raised. * * Note, this feature requires that the user client accepts cookie. Also, to use this feature, * forms submitted via POST method must contain a hidden input whose name is specified by [[csrfParam]]. * You may use [[\yii\helpers\Html::beginForm()]] to generate his hidden input. * * In JavaScript, you may get the values of [[csrfParam]] and [[csrfToken]] via `yii.getCsrfParam()` and * `yii.getCsrfToken()`, respectively. The [[\yii\web\YiiAsset]] asset must be registered. * You also need to include CSRF meta tags in your pages by using [[\yii\helpers\Html::csrfMetaTags()]] |
3.1 ÏÈ¿´¿´ä¯ÀÀÆ÷ÖеÄCSRF¶¼ÓÐÄÄЩÌåÏÖ£º


ÔÚµÚÒ»ÕÅͼƬÖУ¬ºÜÃ÷ÏÔ£¬<meta> ºÍ <form>ÖзֱðÓÐÒ»¸ö
csrf_token£¬²¢ÇÒÊÇÒ»ÖµÄ
ÔÚµÚ¶þÕÂͼƬÖУ¬cookies['_csrf']ÖÐÒ²ÓÐÒ»¸ö¸ü³¤µÄ´®´®£¬Õâ¸öÊÇ¡£¡£¡££¿
¾¹ýÒ»·¬Ñо¿£¬Õâ¸ö³¤³¤µÄ´®ÊÇÒòΪYiiĬÈÏ¿ªÆôÁË cookieValidation
½ûÓÃenableCookieValidationÈ÷ÖÎöCSRFµÄ¹ý³Ì±äµÃ¼òµ¥
ÔÚ configÎļþÖнûÓãº
'components' => [ 'request' => [ // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation 'cookieValidationKey' => '83r5HbITBiMfmiYPOZFdL-raVp4O1VV4', 'enableCookieValidation' => false, 'enableCsrfValidation' => true, ] |
À´¶Ô±ÈϽûÓÃ֮ǰºÍÖ®ºóµÄÇø±ð£º


ÕâÑù _csrf ¾Í¼òµ¥¶àÁË£¬µ±È»ÕâÊDz»°²È«µÄ
3.2 ´Óview¿ªÊ¼Ñ°ÕÒcsrf
3.2.1 ÏÈÕÒÕÒ±íµ¥ÀïµÄ app\views\site\login.php
ûÓÐÕÒµ½csrfµÄ¶¨Òå,ÄÇÓ¦¸ÃÊÇ·â×°µ½ ActiveFormÁË
3.2.2 vendor\yiisoft\yii2\widgets\ActiveForm.php
class ActiveForm extends yii\base\Widget { public function init() { ... echo yii\helpers\Html::beginForm(...); } public function run() { ... echo yii\helpers\Html::endForm(...); } } |
3.2.3 yii\helpers\Html
ÖÕÓÚÕÒµ½ÁËCSRF
public static function beginForm($action = '', $method = 'post', $options = []) { $action = Url::to($action); $hiddenInputs = []; $request = Yii::$app->getRequest(); if ($request->enableCsrfValidation && !strcasecmp($method, 'post')) { $hiddenInputs[] = static::hiddenInput($request->csrfParam, $request->getCsrfToken()); } ... ... |
3.2.4 È¥app\views\layouts\main.php¿´¿´ÀïÃæµÄCSRFÊÇÔõôÀ´µÄ
<head> <meta charset="<?= Yii::$app->charset ?>"/> <meta name="viewport" content="width=device-width, initial-scale=1"> <?= Html::csrfMetaTags() ?> <title><?= Html::encode($this->title) ?></title> <?php $this->head() ?> </head> |
ÕýºÃÒ²ÊÇÔÚ 3.2.3 yii\helpers\HtmlÖж¨ÒåµÄ
/** * Generates the meta tags containing CSRF token information. * @return string the generated meta tags * @see Request::enableCsrfValidation */ public static function csrfMetaTags() { $request = Yii::$app->getRequest(); if ($request instanceof Request && $request->enableCsrfValidation) { return static::tag('meta', '', ['name' => 'csrf-param', 'content' => $request->csrfParam]) . "\n " . static::tag('meta', '', ['name' => 'csrf-token', 'content' => $request->getCsrfToken()]) . "\n"; } else { return ''; }
|
3.2.5 ÔÀ´csrf¶¼ÊÇÓÉ Yii::$app->request´¦ÀíµÄ
headÖÐ
formÖÐ
$request->csrfParam $request->getCsrfToken() |
¿´À´ Õû¸öÑéÖ¤µÄÁ÷³Ì¶¼ÊÇÓÉgetCsrfToken()´¥·¢µÄ¡£
3.3 Ñо¿Ô´Âë
À´¸öÁ÷³Ìͼ(ÊÖ»æ°æ)£º

|