• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

      Django 框架CSRF 防御實(shí)現(xiàn)機(jī)制淺析

      2021-04-24 13:05:10
      關(guān)鍵詞:表單中間件視圖

      (國(guó)防大學(xué)教研保障中心 北京 100091)

      CSRF 攻擊是一種常見的Web 攻擊方式,隨著Web 安全技術(shù)的發(fā)展,各類Web 后端框架,如Laravel、Express、Spring Boot、Django等,都內(nèi)置了CSRF 的防御功能。本文以Django 框架為例,分析其CSRF 防御實(shí)現(xiàn)機(jī)制。

      1 CSRF 攻擊

      CSRF(Cross-site request forgery,跨站請(qǐng)求偽造)是指攻擊者偽裝受信用戶的請(qǐng)求,在受信網(wǎng)站上執(zhí)行被攻擊者非本意操作的攻擊方法。攻擊者使用CSRF 可以利用你的名義發(fā)送郵件消息、盜取賬號(hào)、購買商品、虛擬貨幣轉(zhuǎn)賬等惡意操作,造成個(gè)人隱私泄露以及財(cái)產(chǎn)損失。

      1.1 CSRF 攻擊原理

      http 協(xié)議是無狀態(tài)的,如一個(gè)Web 客戶連續(xù)獲取一個(gè)需要認(rèn)證訪問的Web 服務(wù)器上的信息,可能需要反復(fù)進(jìn)行認(rèn)證。為了解決這個(gè)問題,人們?cè)O(shè)計(jì)了一種得到廣泛應(yīng)用的Cookie 機(jī)制。Cookie 一般由服務(wù)器生成,發(fā)送給瀏覽器,瀏覽器會(huì)將Cookie 的值保存到文本文件中,下次請(qǐng)求同一網(wǎng)站時(shí)就發(fā)送該Cookie 給服務(wù)器,從而實(shí)現(xiàn)保存客戶與服務(wù)器之間的狀態(tài)信息。

      Cookie 最典型的應(yīng)用就是判定注冊(cè)用戶是否已經(jīng)登錄,CSRF 就是通過利用已登錄用戶的Cookie 狀態(tài)信息,偽裝成受信任用戶的請(qǐng)求而實(shí)現(xiàn)攻擊的。例如用戶A 登錄了受信任站點(diǎn)B,用戶A 登錄信息驗(yàn)證通過以后,站點(diǎn)B 會(huì)在返回給用戶A 瀏覽器的信息中帶上已登錄的Cookie 信息;用戶A 在未清除登錄站點(diǎn)B 的Cookie 或Cookie未到期情形下,訪問惡意站點(diǎn)C;惡意站點(diǎn)C 的某個(gè)頁面在返回給用戶A 的數(shù)據(jù)中帶有向站點(diǎn)B 發(fā)起的惡意請(qǐng)求,此時(shí)用戶A 會(huì)自動(dòng)向B 站點(diǎn)發(fā)出請(qǐng)求;站點(diǎn)B 根據(jù)用戶A 請(qǐng)求所帶的Cookie,判斷此請(qǐng)求為受信用戶A 所發(fā)送的。至此,惡意站點(diǎn)C 就達(dá)到了偽造用戶A 請(qǐng)求的目的。

      1.2 CSRF 的防御手段

      (1)驗(yàn)證HTTP Referer

      根據(jù)HTTP 協(xié)議,在 HTTP 頭中有一個(gè)字段叫 Referer,它記錄了該 HTTP 請(qǐng)求的來源地址。因此,要防御 CSRF 攻擊,網(wǎng)站可以驗(yàn)證每一個(gè)訪問安全受限頁面請(qǐng)求的 Referer 值,如果是Referer 值的域名與本網(wǎng)站域名相同或在允許的域名之內(nèi),則說明該請(qǐng)求是來自本網(wǎng)站的請(qǐng)求,是合法的,反之,則有可能是CSRF 攻擊,拒絕該請(qǐng)求。

      (2)增加隨機(jī)Token

      要抵御 CSRF 攻擊,關(guān)鍵在于在請(qǐng)求中放入第三方所不能偽造的信息,且該信息不存在于 Cookie 中,那么可以在 HTTP 請(qǐng)求加入一個(gè)隨機(jī)產(chǎn)生的 Token,并在服務(wù)器端建立一個(gè)攔截器來驗(yàn)證這個(gè)Token,以此判定這個(gè)請(qǐng)求是否偽造。Token 的值必須是隨機(jī)的,可以放入HTTP 請(qǐng)求參數(shù)中或HTTP 請(qǐng)求頭中。

      (3)加入驗(yàn)證碼

      在轉(zhuǎn)賬、刪除、授權(quán)等一些敏感操作的請(qǐng)求中,加入支付密碼或者校驗(yàn)碼等各類人工驗(yàn)證方法,能很好地遏制CSRF 攻擊。

      2 Django 框架CSRF 防御機(jī)制分析

      Django 框架是一個(gè)基于Python 的開源Web 開發(fā)框架,它對(duì)常用Web 開發(fā)模式進(jìn)行了高度封裝。Django 框架在安全方面,為了解決Cookie 存儲(chǔ)數(shù)據(jù)不安全的問題的,Django 框架引入session,用戶瀏覽器只需在Cookie 存儲(chǔ)一個(gè)sessionid,具體的數(shù)據(jù)則通過加密默認(rèn)保存在服務(wù)端session 中,同時(shí)也集成了對(duì)XXS、SQL 注入、CSRF等Web 常見攻擊的防范組件。為實(shí)現(xiàn)CSRF 的防御功能,Django 主要是通過django.middleware.csrf.CsrfViewMiddleware 中間件來實(shí)現(xiàn)。

      2.1 Django 框架中間件

      Django 中間件是一個(gè)輕量的、框架級(jí)別的插件系統(tǒng),用來處理Django 的請(qǐng)求和響應(yīng),在全局范圍內(nèi)改變Django 的輸入和輸出[1]。中間件本質(zhì)上就是一個(gè)自定義類,負(fù)責(zé)實(shí)現(xiàn)一些特定的功能,類中定義了固定的五個(gè)方法:process_request、process_view、process_exception、process_template_responseproces、process_response,Django 會(huì)在瀏覽器請(qǐng)求的特定過程中執(zhí)行這些方法。具體執(zhí)行過程如圖1[2]。

      2.2 Django 框架CSRF 功能設(shè)置

      Django 框架中設(shè)置CSRF 功能可分為全局和局部。全局設(shè)置通過在項(xiàng)目配置文件settings.py 的MIDDLEWARE 參數(shù)中添加刪除中間件django.middleware.csrf.CsrfViewMiddleware 來開啟或者關(guān)閉CSRF 保護(hù)。局部設(shè)置通過@csrf_protect、@csrf_exempt 內(nèi)置裝飾器為視圖函數(shù)強(qiáng)制設(shè)置或關(guān)閉CSRF 功能,即便settings.py 中沒有設(shè)置全局中間件。同時(shí)還需要在前端模板的 Form 表單中加入{%csrf_token %}標(biāo)簽,如果通過AJAX 進(jìn)行提交數(shù)據(jù),則把csrftoken 放入請(qǐng)求頭中提交。

      2.3 Django 框架CSRF 中間件分析

      從源碼分析,CsrfViewMiddleware 中間件下共定義了7 個(gè)方法,其中定義了中間件的process_request、process_view、process_response三個(gè)固有方法以及_accept、_reject、_get_token、_set_token 四個(gè)私有方法。下面簡(jiǎn)要分析下三個(gè)固有方法的主要作用。

      圖1 具體執(zhí)行過程

      (1)process_request 方法

      process_request 方法在Django 接收到http 請(qǐng)求之后,URL 匹配之前調(diào)用。通過_get_token 方法,從request 對(duì)象的Cookie 或session中獲取csrf_token;如果獲取的csrf_token 不為空時(shí),將其賦值給request.META["CSRF_COOKIE"]。

      (2)process_view 方法

      process_view 方法在Django 執(zhí)行URL 匹配之后,執(zhí)行視圖函數(shù)之前調(diào)用。首先判讀視圖函數(shù)是否被裝飾器csrf_exempt 裝飾,如果是則直接執(zhí)行視圖渲染模板。接著判斷request 請(qǐng)求方法是否是GET、HEAD、OPTIONS、TRAC,如果不是以上方法,把request.META["CSRF_COOKIE"]賦值給csrf_token,如果csrf_token為None,則執(zhí)行_reject 方法返回403 錯(cuò)誤頁面;如果csrf_token 不None,且為POST 方法時(shí),則從Form 表單中的csrfmiddlewaretoken字段或 request.META 中的 X-CSRFToken 字段取值并賦值給request_csrf_token。最后通過特定算法對(duì) csrf_token 和request_csrf_token 這兩個(gè)值對(duì)比,相等就執(zhí)行視圖渲染模板,反之直接返回403 錯(cuò)誤頁面。

      (3)process_response 方法

      process_response 方法在所有響應(yīng)返回給瀏覽器之前調(diào)用。通過_set_token 方法設(shè)置 Cookie 或 session 的 csrf_token 值為request.META[“CSRF_COOKIE”],返回response,客戶端瀏覽器完成渲染。

      2.4 模板渲染階段csrf_token 的生成

      從上面CsrfViewMiddleware 中間件功能分析來看,沒有發(fā)現(xiàn)csrf_token 如何初始生成的,其實(shí)初始token 是在視圖渲染階段,通過django.middleware.csrf 模塊的get_token(與私有_get_token 方法不同)函數(shù)生成的。

      在process_request、process_view 方法正常執(zhí)行完之后,就會(huì)執(zhí)行視圖函數(shù)或者視圖類渲染模板。如果在模板中添加了{(lán)%csrf_token%}標(biāo)簽,那么模板在render 函數(shù)渲染過程中,會(huì)在context 字典參數(shù)中加入context['csrf_input']和context['csrf_token'],返回瀏覽器時(shí)會(huì)把{%csrf_token%}替換成Form 表單元素:,其中csrfmiddlewaretoken 值通過get_token 函數(shù)生成。如果表單中沒有{%csrf_token%},渲染的時(shí)候context['csrf_token']不會(huì)被填充,從而不觸發(fā)get_token 方法,也就不會(huì)產(chǎn)生Cookie 信息。

      下面分析 get_token 函數(shù)生成 token 的過程:如果request.META["CSRF_COOKIE"]存在,則取其值,使用_unsalt_cipher_token 函數(shù)解析出32 個(gè)字符的csrf_secret 密鑰;如果request.META["CSRF_COOKIE"]不存在,則使用_get_new_csrf_string函數(shù)重新生成一個(gè) 32 個(gè)字符的 csrf_secret 密鑰,再調(diào)用_salt_cipher_secret 生成一個(gè) 64 個(gè)字符的字符串賦給request.META[“CSRF_COOKIE”]。兩種情況判斷得到的csrf_secret 密鑰,最后通過_salt_cipher_secret 函數(shù)加密返回。需要注意的是_salt_cipher_secret(csrf_secret)每次的返回值都不一樣,但csrf_secret值可以保持不變,也就是說每次刷新頁面時(shí),表單csrfmiddlewaretoken 值是隨機(jī)的,瀏覽器Cookie 值保持不變,可見csrf_secret==_unsalt_cipher_token(_salt_cipher_secret(csrf_secret))。

      2.5 Django 框架CSRF 防御過程分析

      為更清晰的分析CRSF 防御過程,不考慮CsrfViewMiddleware 中間件與Django 其他中間件之間的執(zhí)行流程,只分析該中間件的運(yùn)行機(jī)制。下面我們以用戶提交表單為例進(jìn)行過程分析。

      (1)Django 用戶正常訪問過程分析

      Django 開啟了CRSF 防御,頁面表單嵌入{%csrf_token%},當(dāng)用戶首次打開表單頁面(沒有該網(wǎng)站的Cookie 數(shù)據(jù)),向服務(wù)器發(fā)出GET 請(qǐng)求,Django 在接收到請(qǐng)求之后,第一步分發(fā)到CsrfViewMiddleware 中間件,執(zhí)行process_request 方法,此時(shí)獲取Cookie 信息為空,則進(jìn)行URL 匹配;第二步URL 匹配后執(zhí)行process_view 方法,因請(qǐng)求方法是GET,則直接執(zhí)行視圖函數(shù);第三步視圖函數(shù)根據(jù)GET 請(qǐng)求方法,執(zhí)行相應(yīng)的render 函數(shù)渲染模板,系統(tǒng)檢查到表單嵌入{%csrf_token%},且request.META[“CSRF_COOKIE”]為空,則執(zhí)行g(shù)et_token 函數(shù),生成一個(gè)新的csrf_secret,csrf_secret 利用_salt_cipher_secret 函數(shù)加密返回,同時(shí)把該值賦值給request.META[“CSRF_COOKIE”]和新生成的csrfmiddlewaretoken input 標(biāo)簽。第四步模板渲染完之后會(huì)觸發(fā)process_response,通過_set_token方法把request.META[“CSRF_COOKIE”]等一些其他Cookie 信息存入用戶Cookie 中,把渲染后的模板頁面返回給用戶瀏覽器。這時(shí)用戶瀏覽器中就顯示出表單頁面,同時(shí)表單中含有csrfmiddlewaretoken input標(biāo)簽,Cookie 中包含csrf_token 數(shù)據(jù)。至此一次完整的用戶GET 請(qǐng)求結(jié)束。

      用戶填入表單數(shù)據(jù),向?yàn)g覽器發(fā)出POST 請(qǐng)求。第一步執(zhí)行pro cess_request 方法,通過_get_token 方法獲取Cookie 信息賦值給requ est.META[“CSRF_COOKIE”],經(jīng)URL 匹配后,第二步執(zhí)行process_view 方法,因請(qǐng)求為POST,且request.META["CSRF_COOKIE"]不為空,則分別從Cookie(request.META["CSRF_COOKIE"])和表單中csrfmiddlewaretoken 字段中取值,進(jìn)行算法比較結(jié)果相同,則進(jìn)入第三步執(zhí)行視圖函數(shù),判斷請(qǐng)求方法為POST,執(zhí)行相應(yīng)的處理。第四步把request.META[“CSRF_COOKIE”]值等一些其他Cookie 信息再次存入用戶Cookie 中(Cookie 的值不變,但expire 信息會(huì)有變化),把渲染后的模板頁面返回給用戶瀏覽器。至此用戶POST 請(qǐng)求過程執(zhí)行完畢。

      (2)Django 防御CSRF 攻擊過程分析

      攻擊者在惡意網(wǎng)站中設(shè)置相同的表單字段,利用已登錄用戶的Cookie 狀態(tài)信息(此時(shí)Cookie 中有數(shù)據(jù)),向授信網(wǎng)站發(fā)出POST 請(qǐng)求,當(dāng)請(qǐng)求執(zhí)行CSRF 中間件的process_view 方法時(shí),因攻擊請(qǐng)求的表單字段中不包含csrfmiddlewaretoken 字段,則直接返回403 錯(cuò)誤頁面。

      Django 設(shè)計(jì)CSRF 防御方法中,csrfmiddlewaretoken 字段的值是隨機(jī)變化的,且采用了加密算法,攻擊者很難模擬csrfmiddlewaretoken 的值。為了用戶更加安全,防止Cookie 信息泄露,Django 的Cookie 信息加密放入session 中。

      3 結(jié)束語

      目前主流Web 框架都已加入CSRF 防御功能,且配置過程簡(jiǎn)單,但大多數(shù)人對(duì)框架CSRF 防御機(jī)制了解不多,通過本文對(duì)Django 框架的CSRF 防御原理和實(shí)現(xiàn)機(jī)制的分析,希望給大家對(duì)CSRF 攻擊的原理和Django 框架CSRF 防御架構(gòu)設(shè)計(jì)提供一些參考,同時(shí)進(jìn)一步增強(qiáng)大家的Web 安全防范意識(shí)。

      猜你喜歡
      表單中間件視圖
      電子表單系統(tǒng)應(yīng)用分析
      華東科技(2021年9期)2021-09-23 02:15:24
      RFID中間件技術(shù)及其應(yīng)用研究
      電子制作(2018年14期)2018-08-21 01:38:10
      基于VanConnect中間件的設(shè)計(jì)與開發(fā)
      淺談網(wǎng)頁制作中表單的教學(xué)
      5.3 視圖與投影
      視圖
      Y—20重型運(yùn)輸機(jī)多視圖
      SA2型76毫米車載高炮多視圖
      中間件在高速公路領(lǐng)域的應(yīng)用
      一種支持智能環(huán)境構(gòu)建的中間件
      汤阴县| 民丰县| 隆林| 湾仔区| 盐源县| 平泉县| 呼伦贝尔市| 横山县| 喀喇沁旗| 汨罗市| 鄂托克前旗| 彰武县| 金寨县| 灵台县| 甘德县| 宝坻区| 昌宁县| 土默特右旗| 金湖县| 拉孜县| 灵川县| 永昌县| 易门县| 永靖县| 庆安县| 屏东市| 昌邑市| 西畴县| 三都| 崇礼县| 巩留县| 九台市| 壶关县| 桓台县| 毕节市| 元朗区| 天镇县| 定州市| 高陵县| 自贡市| 永修县|