Laravel Http層 CSRF保護(hù)

什么是CSRF攻擊

CSRF是跨站請求偽造(Cross-site request forgery)的英文縮寫。CSRF是跨站請求偽造(CSRF)是一種通過偽裝授權(quán)用戶的請求來利用授信網(wǎng)站的惡意漏洞钻弄。

關(guān)于CSRF攻擊原理及其防護(hù),可查看Github上的這個(gè)項(xiàng)目:理解CSRF肘习,說得比較詳細(xì)和透徹泛源。

Laravel 中如何避免CSRF攻擊

Laravel 讓應(yīng)用避免遭到跨站請求偽造攻擊變得簡單。

Laravel框架中避免CSRF攻擊很簡單:Laravel自動(dòng)為每個(gè)用戶Session生成了一個(gè)CSRF Token薪者,該Token可用于驗(yàn)證登錄用戶和發(fā)起請求者是否是同一人竿裂,如果不是則請求失敗玉吁。

Laravel提供了一個(gè)全局幫助函數(shù)csrf_token來獲取該Token值,因此只需在視提交圖表單中添加如下HTML代碼即可在請求中帶上Token:

<form method="POST" action="/profile"> 
  {{ csrf_field() }}
   ...
</form>

中間件組 web中的中間件 VerifyCsrfToken 會自動(dòng)為我們驗(yàn)證請求輸入的 token 值和 Session中存儲的 token 是否一致腻异。

從 CSRF 保護(hù)中排除指定 URL

并不是所有請求都需要避免CSRF攻擊进副,比如去第三方API獲取數(shù)據(jù)的請求』诔#可以通過在 VerifyCsrfToken 中間件中將要排除的請求URL添加到 $except 屬性數(shù)組中:

<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;

class VerifyCsrfToken extends BaseVerifier{
   /**
    * 指定從 CSRF 驗(yàn)證中排除的URL
    *
    * @var array
    */
  protected $except = [ 
   'testCsrf',
  ];
}

這樣我們刷新頁面影斑,再次在http://laravel.app:8000/testCsrf頁面中點(diǎn)擊“Test”按鈕,則頁面不會報(bào)錯(cuò)机打,正常輸出如下內(nèi)容:

Success!

X-CSRF-Token 及其使用

如果使用 Ajax 提交POST表單矫户,又該如何處理呢?我們可以將Token設(shè)置在meta中:

<meta name="csrf-token" content="{{ csrf_token() }}">

然后在全局Ajax中使用這種方式設(shè)置X-CSRF-Token請求頭并提交:

$.ajaxSetup({ 
  headers: {
     'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') 
  }
});

Laravel 的VerifyCsrfToken中間件會檢查X-CSRF-TOKEN請求頭残邀,如果該值和SessionCSRF值相等則驗(yàn)證通過皆辽,否則不通過。

X-XSRF-Token 及其使用

除此之外芥挣,Laravel還會將CSRF的值保存到名為XSRF-TOKENCookie 中膳汪,然后在VerifyCsrfToken 中間件驗(yàn)證該值,當(dāng)然九秀,我們不需要手動(dòng)做任何操作,一些JavaScript框架如Angular會自動(dòng)幫我們實(shí)現(xiàn)粘我。

Laravel中CSRF驗(yàn)證原理分析

首先

首先Laravel開啟Session時(shí)會生成一個(gè)token值并存放在Session中(Illuminate\Session\Store.php 第90行start 方法)鼓蜒,對應(yīng)源碼如下:

public function start()
{
    $this->loadSession();

    if (! $this->has('_token')) {
        $this->regenerateToken();
    }

    return $this->started = true;
}

然后

然后重點(diǎn)分析VerifyToken中間件的handle方法痹换,該方法中先通過 isReading 方法判斷請求方式,如果請求方法是 HEAD都弹、GET娇豫、OPTIONS 其中一種,則不做CSRF驗(yàn)證畅厢;

再然后

再通過shouldPassThrough方法判斷請求路由是否在$excpet
屬性數(shù)組中進(jìn)行了排除冯痢,如果做了排除也不做驗(yàn)證;

最后

最后通過 tokensMatch 方法判斷請求參數(shù)中的 CSRF TOKEN值和Session中的Token值是否相等框杜,如果相等則通過驗(yàn)證浦楣,否則拋出TokenMismatchException異常。對應(yīng)源碼如下:

public function handle($request, Closure $next)
{
    if ($this->isReading($request) || $this->shouldPassThrough($request) || $this->tokensMatch($request)) {
        return $this->addCookieToResponse($request, $next($request));
    }

    throw new TokenMismatchException;
}

注:tokensMatch 方法首先從 Request 中獲取 _token 參數(shù)值咪辱,如果請求中不包含該參數(shù)則獲取X-CSRF-TOKEN 請求頭的值振劳,如果該請求頭也不存在則獲取X-XSRF-TOKEN 請求頭的值,需要注意的是X-XSRF-TOKEN 請求頭的值需要調(diào)用Encrypterdecrypt方法進(jìn)行解密油狂。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末历恐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子专筷,更是在濱河造成了極大的恐慌弱贼,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件磷蛹,死亡現(xiàn)場離奇詭異吮旅,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)弦聂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門鸟辅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人莺葫,你說我怎么就攤上這事匪凉。” “怎么了捺檬?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵再层,是天一觀的道長。 經(jīng)常有香客問我堡纬,道長聂受,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任烤镐,我火速辦了婚禮蛋济,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘炮叶。我一直安慰自己碗旅,他們只是感情好渡处,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著祟辟,像睡著了一般医瘫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旧困,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天醇份,我揣著相機(jī)與錄音,去河邊找鬼吼具。 笑死僚纷,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的馍悟。 我是一名探鬼主播畔濒,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼锣咒!你這毒婦竟也來了侵状?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤毅整,失蹤者是張志新(化名)和其女友劉穎趣兄,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悼嫉,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡艇潭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了戏蔑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹋凝。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖总棵,靈堂內(nèi)的尸體忽然破棺而出鳍寂,到底是詐尸還是另有隱情,我是刑警寧澤情龄,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布迄汛,位于F島的核電站,受9級特大地震影響骤视,放射性物質(zhì)發(fā)生泄漏鞍爱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一专酗、第九天 我趴在偏房一處隱蔽的房頂上張望睹逃。 院中可真熱鬧,春花似錦祷肯、人聲如沸唯卖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拜轨。三九已至,卻和暖如春允青,著一層夾襖步出監(jiān)牢的瞬間橄碾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工颠锉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留法牲,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓琼掠,卻偏偏與公主長得像拒垃,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子瓷蛙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容