国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

從Yii2的Request看其CSRF防范策略

2019-11-15 01:47:25
字體:
來源:轉載
供稿:網友
從Yii2的Request看其CSRF防范策略

先畫一幅流程圖理理思路:

yii2-csrf-yii-request

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攻擊,暫時用下面的辦法將其禁用。

http://stackoverflow.com/questions/23237377/yii2-curl-bad-request-400

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 攻擊?

簡單說, 攻擊者盜用了你的身份,以你的名義發送惡意請求。

http://m.survivalescaperooms.com/hyddd/archive/2009/04/09/1432744.htmlhttp://baike.baidu.com/view/1609487.htm?fr=aladdin

最有效地一個方法原理是這樣的:

  • Cookie Hashing, 讓服務器發送給客戶端的所有表單中都標示一個隨機值_csrf,并同時在客戶端的COOKIE中保存一個相關聯的token;
  • 驗證的時候,服務端每次對接收到的請求_POST()過來的一個input hidden _csrf跟客戶端的COOKIE中的token進行對照驗證
  • 攻擊者攻擊的原理是利用了客戶端的COOKIE,但是攻擊者是得不到COOKIE具體的內容的,他只是利用(這里拋開XSS攻擊的可能性,由于用戶的Cookie很容易由于網站的XSS漏洞而被盜取,這就另外的1%。一般的攻擊者看到有需要算Hash值,基本都會放棄了);所以攻擊者沒法在攻擊URL中加入token,這樣就無法通過驗證。

這可能是最簡單的解決方案了,因為攻擊者不能獲得第三方的Cookie(理論上),所以表單中的數據也就構造失敗了:>

來看看:Yii2是不是這么干的。

3. 從外到內探究

原創文章,http://m.survivalescaperooms.com/ganiks/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 就簡單多了,當然這是不安全的

3.2 從view開始尋找csrf3.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>

原創文章,http://m.survivalescaperooms.com/ganiks/正好也是在 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中

    $request->getCsrfToken()
  • form中

    $request->csrfParam$request->getCsrfToken()

    看來 整個驗證的流程都是由getCsrfToken()觸發的。

3.3 研究源碼

源碼請參考:http://www.yiiframework.com/doc-2.0/yii-web-request.html

來個流程圖(手繪版):

yii2-csrf-yii-request


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 达孜县| 民乐县| 方山县| 阳江市| 邵东县| 财经| 中山市| 金堂县| 北碚区| 宁武县| 黑河市| 哈尔滨市| 岳普湖县| 湟源县| 凤凰县| 汝阳县| 宣威市| 榕江县| 墨江| 金川县| 嘉善县| 垫江县| 时尚| 宁海县| 晋宁县| 明星| 宁化县| 崇州市| 桐梓县| 河东区| 察哈| 道孚县| 托克托县| 南京市| 合阳县| 汤原县| 淳化县| 德令哈市| 徐汇区| 龙胜| 昌都县|