日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
前后端分離架構(gòu)下CSRF防御機制

背景

1、什么是CSRF攻擊?

這里不再介紹CSRF,已經(jīng)了解CSRF原理的同學(xué)可以直接跳到:“3、前后端分離下有何不同?”。

不太了解的同學(xué)可以看這兩篇對CSRF介紹比較詳細(xì)的參考文章:

  • CSRF 攻擊的應(yīng)對之道
  • 淺談CSRF攻擊方式

如果來不及了解CSRF的原理,可以這么理解:有一個人發(fā)給你一個搞(mei)笑(nv)圖片鏈接,你打開這個鏈接之后,便立刻收到了短信:你的銀行里的錢已經(jīng)轉(zhuǎn)移到這個人的帳戶了。

2、有哪些防御方案?

上面這個例子當(dāng)然有點危言聳聽,當(dāng)然可以確定的是確實會有這樣的漏洞:你打開了一個未知域名的鏈接,然后你就自動發(fā)了條廣告帖子、你的Gmail的郵件內(nèi)容就泄露了、你的百度登錄狀態(tài)就沒了……

防御方案在上面的兩篇文章里也有提到,總結(jié)下,無外乎三種:

  • 用戶操作限制,比如驗證碼;
  • 請求來源限制,比如限制HTTP Referer才能完成操作;
  • token驗證機制,比如請求數(shù)據(jù)字段中添加一個token,響應(yīng)請求時校驗其有效性;

第一種方案明顯嚴(yán)重影響了用戶體驗,而且還有額外的開發(fā)成本;第二種方案成本最低,但是并不能保證100%安全,而且很有可能會埋坑;第三種方案,可取!

token驗證的CSRF防御機制是公認(rèn)最合適的方案,也是本文討論的重點。

3、前后端分離下有何不同?

《CSRF 攻擊的應(yīng)對之道》這篇文章里有提到:

要把所有請求都改為 XMLHttpRequest 請求,這樣幾乎是要重寫整個網(wǎng)站,這代價無疑是不能接受的

我們前端架構(gòu)早已經(jīng)告別了服務(wù)端語言(PHP/JAVA等)綁定路由、攜帶數(shù)據(jù)渲染模板引擎的方式(畢竟是2011年的文章了,我們笑而不語)。

當(dāng)然, 前端不要高興的太早:前后端分離之后,Nodejs不具備完善的服務(wù)端SESSION、數(shù)據(jù)庫等功能。

總結(jié)一下,在“更先進(jìn)”的前端架構(gòu)下,與以往的架構(gòu)會有一些區(qū)別:

  • Nodejs層不處理SESSION,無法直接實現(xiàn)會話狀態(tài)數(shù)據(jù)保存;
  • 所有的數(shù)據(jù)通過Ajax異步獲取,可以靈活實現(xiàn)token方案;

實現(xiàn)思路

如上文提到,這里僅僅討論在“更先進(jìn)”的前端后端架構(gòu)背景下的token防御方案的實現(xiàn)。

1、可行性方案

token防御的整體思路是:

  • 第一步:后端隨機產(chǎn)生一個token,把這個token保存在SESSION狀態(tài)中;同時,后端把這個token交給前端頁面;
  • 第二步:下次前端需要發(fā)起請求(比如發(fā)帖)的時候把這個token加入到請求數(shù)據(jù)或者頭信息中,一起傳給后端;
  • 第三步:后端校驗前端請求帶過來的token和SESSION里的token是否一致;

上文提到過,前后端分離狀態(tài)下,Nodejs是不具備SESSION功能的。那這種token防御機制是不是就無法實現(xiàn)了呢?

肯定不是。我們可以借助cookie把這個流程升級下:

  • 第一步:后端隨機產(chǎn)生一個token,基于這個token通過SHA-56等散列算法生成一個密文;
  • 第二步:后端將這個token和生成的密文都設(shè)置為cookie,返回給前端;
  • 第三步:前端需要發(fā)起請求的時候,從cookie中獲取token,把這個token加入到請求數(shù)據(jù)或者頭信息中,一起傳給后端;
  • 第四步:后端校驗cookie中的密文,以及前端請求帶過來的token,進(jìn)行正向散列驗證;

當(dāng)然這樣實現(xiàn)也有需要注意的:

  • 散列算法都是需要計算的,這里會有性能風(fēng)險;
  • token參數(shù)必須由前端處理之后交給后端,而不能直接通過cookie;
  • cookie更臃腫,會不可避免地讓頭信息更重;

現(xiàn)在方案確定了,具體該如何實現(xiàn)呢?

2、具體實現(xiàn)

我們的技術(shù)棧是 koa(服務(wù)端) + Vue.js(前端) 。有興趣可以看這些資料:

  • 趣店前端團隊基于koajs的前后端分離實踐
  • koa-grace——基于koa的標(biāo)準(zhǔn)前后端分離框架
  • grace-vue-webpack-boilerplate

在服務(wù)端,實現(xiàn)了一個token生成的中間件,koa-grace-csrf:

 
 
 
  1. // 注意:代碼有做精簡
  2.  
  3.  const tokens = require('./lib/tokens');
  4.  return function* csrf(next) {
  5.    let curSecret = this.cookies.get('密文的cookie');
  6.    // 其他如果要獲取參數(shù),則為配置參數(shù)值
  7.    let curToken = '請求http頭信息中的token';
  8.    
  9.    // token不存在
  10.    if (!curToken || !curSecret) {
  11.      return this.throw('CSRF Token Not Found!',403)
  12.    }
  13.    // token校驗失敗
  14.    if (!tokens.verify(curSecret, curToken)) {
  15.      return this.throw('CSRF token Invalid!',403)
  16.    }
  17.    yield next;
  18.    // 無論何種情況都種兩個cookie
  19.    // cookie_key: 當(dāng)前token的cookie_key,httpOnly
  20.    let secret = tokens.secretSync();
  21.    this.cookies.set(options.cookie_key, secret);
  22.    // cookie_token: 當(dāng)前token的的content,不需要httpOnly
  23.    let newToken = tokens.create(secret);
  24.    this.cookies.set(options.cookie_token, newToken)
  25.  } 

在前端代碼中,對發(fā)送ajax請求的封裝稍作優(yōu)化:

 
 
 
  1. this.$http.post(url, data, {
  2.       headers: {
  3.           'http請求頭信息字段名': 'cookie中的token'
  4.       }
  5.   }).then((res) => {}) 

總結(jié)一下:

  • Nodejs生成一個隨機數(shù),通過隨機數(shù)生成散列密文;并將隨機數(shù)和密文存到cookie;
  • 客戶端JS獲取cookie中的隨機數(shù),通過http頭信息交給Nodejs;
  • Nodejs響應(yīng)請求,校驗cookie中的密文和頭信息中的隨機數(shù)是否匹配;

這里依舊有個細(xì)節(jié)值得提一下:Nodejs的上層一般是nginx,而nginx默認(rèn)會過濾頭信息中不合法的字段(比如頭信息字段名包含“_”的),這里在寫頭信息的時候需要注意。

上文也提到,通過cookie及http頭信息傳遞加密token會有很多弊端;有沒有更優(yōu)雅的實現(xiàn)方案呢?

3、更優(yōu)雅的架構(gòu)

首先,我們明確前后端分離的一些基本原則:

后端(Java / PHP )職責(zé):

  • 服務(wù)層顆?;涌冢员闱岸薔odejs層異步并發(fā)調(diào)用;
  • 用戶狀態(tài)保存,實現(xiàn)用戶權(quán)限等各種功能;

前端(Nodejs + Javascript)職責(zé):

  • Nodejs層完成路由托管及模板引擎渲染功能
  • Nodejs層不負(fù)責(zé)實現(xiàn)任何SESSION和數(shù)據(jù)庫功能

我們提到,前端Nodejs層不負(fù)責(zé)實現(xiàn)任何SESSION和數(shù)據(jù)庫功能,但有沒有可能把后端緩存系統(tǒng)做成公共服務(wù)提供給Nodejs層使用呢?想想感覺前端整條路都亮了有木有?!這里先挖一個坑,后續(xù)慢慢填。

4、延伸

這里再順便提一下,新架構(gòu)下的XSS防御。

猶記得,在狼廠使用PHP的年代,經(jīng)常被安全部門曝出各類XSS漏洞,然后就在smaty里添加各種escape濾鏡,但是添加之后發(fā)現(xiàn)竟然把原始數(shù)據(jù)也給轉(zhuǎn)義了。

當(dāng)然,現(xiàn)在更多要歸功于各種MVVM單頁面應(yīng)用:使得前端完全不需要通過讀取URL中的參數(shù)來控制VIEW。

不過,還有一點值得一提:前后端分離框架下,路由由Nodejs控制;我自己要獲取的后端參數(shù)和需要用在業(yè)務(wù)邏輯的參數(shù),在主觀上前端同學(xué)更好把握一些。

所以, 在koa(服務(wù)端) + Vue.js(前端)架構(gòu)下基本不用顧慮XSS問題(至少不會被全安組追著問XSS漏洞啥時候修復(fù))。

總結(jié)

要不學(xué)PHP、看Java、玩Python做全棧好了?


文章名稱:前后端分離架構(gòu)下CSRF防御機制
URL網(wǎng)址:http://www.dlmjj.cn/article/coishop.html