国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

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

2021-04-24 13:05:10
網(wǎng)絡安全技術與應用 2021年4期
關鍵詞:表單中間件視圖

(國防大學教研保障中心 北京 100091)

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

1 CSRF 攻擊

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

1.1 CSRF 攻擊原理

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

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

1.2 CSRF 的防御手段

(1)驗證HTTP Referer

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

(2)增加隨機Token

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

(3)加入驗證碼

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

2 Django 框架CSRF 防御機制分析

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

2.1 Django 框架中間件

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

2.2 Django 框架CSRF 功能設置

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

2.3 Django 框架CSRF 中間件分析

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

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

(1)process_request 方法

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

(2)process_view 方法

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

(3)process_response 方法

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

2.4 模板渲染階段csrf_token 的生成

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

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

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

2.5 Django 框架CSRF 防御過程分析

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

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

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

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

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

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

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

3 結束語

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

猜你喜歡
表單中間件視圖
電子表單系統(tǒng)應用分析
華東科技(2021年9期)2021-09-23 02:15:24
RFID中間件技術及其應用研究
電子制作(2018年14期)2018-08-21 01:38:10
基于VanConnect中間件的設計與開發(fā)
電子測試(2018年10期)2018-06-26 05:54:02
淺談網(wǎng)頁制作中表單的教學
5.3 視圖與投影
視圖
Y—20重型運輸機多視圖
SA2型76毫米車載高炮多視圖
中間件在高速公路領域的應用
一種支持智能環(huán)境構建的中間件
浙江省| 邮箱| 东山县| 青铜峡市| 晋中市| 江西省| 庄河市| 旬阳县| 凤翔县| 临安市| 西林县| 上虞市| 安西县| 繁昌县| 疏勒县| 当阳市| 大竹县| 涿州市| 大余县| 望城县| 大渡口区| 阜新| 古交市| 西乌珠穆沁旗| 郴州市| 当雄县| 白银市| 涿鹿县| 铜川市| 宜章县| 朔州市| 万盛区| 祁门县| 潞西市| 高青县| 伊宁市| 青浦区| 淅川县| 惠州市| 涞水县| 于田县|