Python Web 開發(fā)筆記(2)

登錄流程及防止跨域偽造攻擊

第 1 步

瀏覽器使用 POST 方法發(fā)送登錄請(qǐng)求。

服務(wù)器收到瀏覽器發(fā)來(lái)的請(qǐng)求,F(xiàn)lask 框架在處理請(qǐng)求的時(shí)候,利用 Flask-WTF 插件生成一個(gè)隨機(jī)的字符串,下圖所示:

40 位 16 進(jìn)制的隨機(jī)字符串

這個(gè)就是 csrf_token 字段,它會(huì)經(jīng)過(guò) A 令牌生成器生成一個(gè)令牌塞到響應(yīng) body 的表單的隱藏域里。

第 2 步

每個(gè)請(qǐng)求都由一個(gè)單獨(dú)的線程處理,這個(gè)線程會(huì)創(chuàng)建一個(gè)請(qǐng)求上下文對(duì)象,它有個(gè) session 屬性,屬性值是類字典對(duì)象。

捎帶腳,這個(gè)「 csrf_token 字段及其值」會(huì)作為「請(qǐng)求上下文對(duì)象的 session 屬性值」的鍵值對(duì),這個(gè)字典的鍵值對(duì)可能很多,例如 _id (它是根據(jù) IP 地址和 USER_AGENT 生成的 128 位字符串)、_user_id 是用戶存在數(shù)據(jù)庫(kù)里的主鍵等等。

先瞎編一個(gè)字典:

然后有一個(gè) B 令牌生成器將「請(qǐng)求對(duì)象的 session 屬性值」作為參數(shù)調(diào)用令牌生成器的 dumps 方法,就生成了一個(gè)字符串,它就是 session

這個(gè) session 字符串會(huì)被扔到響應(yīng)對(duì)象的頭部字典的 Set-Cookie 鍵中,粗略代碼如下:

response.headers.add('Set-Cookie', b'session={}'.format(session))

響應(yīng)對(duì)象傳回瀏覽器,瀏覽器設(shè)置 Cookies 后,Cookies 鍵值對(duì)中就有了 session 字段。

額外說(shuō)明:瀏覽器首次訪問(wèn)網(wǎng)站時(shí),F(xiàn)lask Web 應(yīng)用也會(huì)在響應(yīng)對(duì)象中提供一個(gè) session ,如果響應(yīng) body 有表單,也會(huì)在隱藏域中提供 csrf_token 。

第 3 步

瀏覽器再次發(fā)送了一個(gè)請(qǐng)求,假設(shè)是帶表單的 POST 請(qǐng)求,修改用戶信息之類的操作。

這個(gè)請(qǐng)求對(duì)象里就攜帶了 cookies 和表單,表單里有 csrf_token 的加密令牌。

服務(wù)器收到請(qǐng)求后,把表單隱藏域中的值拿出來(lái)使用 A 令牌生成器解密并賦值給一個(gè)變量,我們假設(shè)它是 c1 。

把 cookies 里的 session 字段的值拿出來(lái),使用 B 令牌生成器解密得到字典:

然后從中拿出 csrf_token 字段的值跟 c1 比較,就可以判斷這個(gè)請(qǐng)求了。

如果壞人使用「跨域偽造攻擊」,可以得到用戶瀏覽器上的 cookies ,也就得到了 session ,但它得不到表單隱藏域 csrf_token ,這個(gè) csrf_token 跟 session 是一套。

防止 CSRF 跨域偽造攻擊

  • 用戶訪問(wèn)「某某銀行」的網(wǎng)站,登錄后,瀏覽器保存帶有 session 的 Cookies

  • 而 csrf_token 呢,它作為一個(gè) 40 位的字符串,會(huì)被加密成一個(gè)更復(fù)雜的字符串

  • 這個(gè)字符串被放到響應(yīng)對(duì)象的 body 中的表單的隱藏域里頭,返回給瀏覽器

  • 也就是說(shuō)只有包含表單的頁(yè)面才有這個(gè) csrf_token ,下圖所示:

  • 現(xiàn)在攻擊者誘導(dǎo)用戶訪問(wèn)釣魚網(wǎng)站,釣魚網(wǎng)站獲取用戶的 Cookie
  • 然后自動(dòng)使用 POST 方法訪問(wèn)地址,這個(gè)地址就是轉(zhuǎn)賬請(qǐng)求,這個(gè)請(qǐng)求會(huì)帶上偷來(lái)的 Cookie
  • 雖然有偷來(lái)的 Cookie ,但沒(méi)有表單的隱藏字段 csrf_token ,所以請(qǐng)求會(huì)失敗
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容