?? 歡迎大家來到景天科技苑??
???? 養(yǎng)成好習(xí)慣,先贊后看哦~????
?? 作者簡介:景天科技苑
??《頭銜》:大廠架構(gòu)師,華為云開發(fā)者社區(qū)專家博主,阿里云開發(fā)者社區(qū)專家博主,CSDN全棧領(lǐng)域優(yōu)質(zhì)創(chuàng)作者,掘金優(yōu)秀博主,51CTO博客專家等。
??《博客》:Python全棧,前后端開發(fā),人工智能,js逆向,App逆向,網(wǎng)絡(luò)系統(tǒng)安全,數(shù)據(jù)分析,Django,fastapi,flask等框架,linux,shell腳本等實(shí)操經(jīng)驗(yàn),網(wǎng)站搭建,面試寶典等分享。所屬的專欄:flask框架零基礎(chǔ),進(jìn)階應(yīng)用實(shí)戰(zhàn)教學(xué)
景天的主頁:景天科技苑
CSRF攻擊防范
詳述CSRF(Cross-site request forgery),中文名稱:跨站請求偽造,也被稱為:one click attack/session riding,縮寫為:CSRF/XSRF。
攻擊者通過HTTP請求將數(shù)據(jù)傳送到服務(wù)器,從而盜取回話的cookie。盜取會(huì)話cookie之后,攻擊者不僅可以獲取用戶的信息,還可以修改該cookie關(guān)聯(lián)的賬戶信息。
跨站請求攻擊,簡單地說,是攻擊者通過一些技術(shù)手段欺騙用戶的瀏覽器去訪問一個(gè)自己曾經(jīng)認(rèn)證過的網(wǎng)站并運(yùn)行一些操作(如發(fā)郵件,發(fā)消息,甚至財(cái)產(chǎn)操作如轉(zhuǎn)賬和購買商品)。由于瀏覽器曾經(jīng)認(rèn)證過,所以被訪問的網(wǎng)站會(huì)認(rèn)為是真正的用戶操作而去運(yùn)行。這利用了web中用戶身份驗(yàn)證的一個(gè)漏洞:簡單的身份驗(yàn)證只能保證請求發(fā)自某個(gè)用戶的瀏覽器,卻不能保證請求本身是用戶自愿發(fā)出的。
CSRF防范方式一:
同源檢測
Cookie的同源和瀏覽器的同源策略有所區(qū)別:
-
瀏覽器同源策略:協(xié)議、域名和端口都相同即同源;
-
Cookie同源策略:域名相同即同源;
在HTTP協(xié)議中,每個(gè)異步請求都會(huì)攜帶兩個(gè)header,用來標(biāo)記來源域名: -
Origin Header
-
Referer Header
這兩個(gè)Header在瀏覽器發(fā)起請求時(shí),大多數(shù)情況會(huì)自動(dòng)帶上,并且不能由前端修改,服務(wù)器接收到后可以根據(jù)這兩個(gè)Header確定來源的域名;
特殊情況: 如果Origin和Referer都不存在,建議直接進(jìn)行阻止,特別是如果您沒有使用隨機(jī)CSRF Token(參考下方)作為第二次檢查。
另外,CSRF大多數(shù)情況下來自第三方域名,但并不能排除本域發(fā)起。如果攻擊者有權(quán)限在本域發(fā)布評論(含鏈接、圖片等),那么它可以直接在本域發(fā)起攻擊,這種情況下同源策略無法達(dá)到防護(hù)的作用。
CSRF防范方式二:
添加校驗(yàn)token
由于CSRF的本質(zhì)在于攻擊者欺騙用戶去訪問自己設(shè)置的地址,所以如果要求在訪問敏感數(shù)據(jù)請求時(shí),要求用戶瀏覽器提供不保存在cookie中,并且攻擊者無法偽造的數(shù)據(jù)作為校驗(yàn),那么攻擊者就無法再運(yùn)行CSRF攻擊。這種數(shù)據(jù)通常是窗體中的一個(gè)數(shù)據(jù)項(xiàng)。服務(wù)器將其生成并附加在窗體中,其內(nèi)容是一個(gè)偽隨機(jī)數(shù)。當(dāng)客戶端通過窗體提交請求時(shí),這個(gè)偽隨機(jī)數(shù)也一并提交上去以供校驗(yàn)。正常的訪問時(shí),客戶端瀏覽器能夠正確得到并傳回這個(gè)偽隨機(jī)數(shù),而通過CSRF傳來的欺騙性攻擊中,攻擊者無從事先得知這個(gè)偽隨機(jī)數(shù)的值,服務(wù)端就會(huì)因?yàn)樾r?yàn)token的值為空或者錯(cuò)誤,拒絕這個(gè)可疑請求
CSRF: 跨域請求偽造攻擊。flask預(yù)防CSRF攻擊需要下載包,flask_wtf。這個(gè)就是基于token校驗(yàn)來防范CSRF攻擊的。
插件下載
pip install flask_wtf
flask_wtf本身提供了生成表單HTML頁面的功能(基于wtforms提供),常用于開發(fā)前后端不分離的表單頁面,
同時(shí)Flask-wtf 擴(kuò)展模塊還提供了一套完善的 csrf 防護(hù)體系,對于我們開發(fā)者來說,使用flask_wtf模塊就可以非常簡單解決CSRF攻擊問題。
工作流程
1 在表單響應(yīng)的頁面中加入{% csrf_token %}標(biāo)簽,那么在進(jìn)行模板渲染是會(huì)生成如下標(biāo)簽
<input type="hidden" name="csrfmiddlewaretoken" value="ppwN8yg1wVEyXDxtMpVIrc4zV3gHiDKKb9rwGPLaSGRc0HKhXAwpNrKjGDUHIxjj">
2 并且在響應(yīng)還有這個(gè){% csrf_token %}標(biāo)簽的頁面時(shí),會(huì)添加cookie鍵值對,如下
csrftoken:lsMQeJgVbIKKxlfz6umgYM8WOWx1Njr77cHzM0L4xtXoApsnhFXXk1OGzwb1dd0G
3 當(dāng)用戶從該頁面提交數(shù)據(jù)時(shí),會(huì)攜帶csrfmiddlewaretoken:ppwN8yg1wVEyXDxtMpVIrc4zV3gHiDKKb9rwGPLaSGRc0HKhXAwpNrKjGDUHIxjj和cookie鍵值對
4 取出cookie中的csrftoken值和請求數(shù)據(jù)部分的csrfmiddlewaretoken的值,兩者進(jìn)行比較,這個(gè)隨機(jī)字符串叫做token字符串.
flask如果在請求數(shù)據(jù)部分找tokne值,如果這個(gè)鍵對應(yīng)的值和cookie中csrftoken對應(yīng)的值相同,也能通過認(rèn)證.
具體配置
- 設(shè)置應(yīng)用程序的 secret_key,用于加密生成的 csrf_token 的值
#1. session加密的時(shí)候已經(jīng)配置過了.如果沒有在配置項(xiàng)中設(shè)置,則如下:
app.secret_key = "#此處可以寫隨機(jī)字符串#"
#2. 也可以寫在配置類中。
class Config(object):
DEBUG = True
SECRET_KEY = "dsad32DASSLD*13%^32"
"""加載配置"""
app.config.from_object(Config)
- 導(dǎo)入 flask_wtf 中的 CSRFProtect類,進(jìn)行初始化,并在初始化的時(shí)候關(guān)聯(lián) app
# 方式1:
from flask_wtf import CSRFProtect
csrf = CSRFProtect() # 這塊代碼可能在文件中。
app = Flask(import_name=__name__, template_folder="templates")
# 項(xiàng)目配置代碼之后
csrf.init_app(app) # 避免出現(xiàn)引用導(dǎo)包,所以提供了init_app的用法
# 方式2:
# from flask_wtf import CSRFProtect
# app = Flask(import_name=__name__, template_folder="templates")
# 項(xiàng)目配置代碼之后
# CSRFProtect(app)
完整視圖代碼
from flask import Flask, render_template
from flask_wtf import CSRFProtect
csrf = CSRFProtect() # 這塊代碼可能在文件中。
app = Flask(import_name=__name__, template_folder="templates")
# 項(xiàng)目配置代碼之后
csrf.init_app(app) # 將插件注冊到app中去
#設(shè)置應(yīng)用程序的 secret_key,用于加密生成的 csrf_token 的值
app.config['SECRET_KEY'] = 'dafssg231bfvxvdsfwrqdqfafaffsgsbfsfsgs'
@app.route("/user")
def user():
title = "用戶中心"
html = render_template("index12.html", **locals())
return html
@app.route("/transfer", methods=["post"])
def transfer():
return "轉(zhuǎn)賬成功!"
if __name__ == '__main__':
app.run(debug=True)
在表單中使用 CSRF 令牌
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="http://127.0.0.1:5000/transfer" method="post">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
賬號(hào):<input type="text" name="username"><br><br>
密碼:<input type="text" name="password"><br><br>
<input type="submit" value="轉(zhuǎn)賬">
</form>
</body>
</html>
瀏覽器訪問/user頁面,表單里面會(huì)多一個(gè)隱藏的input標(biāo)簽,
當(dāng)我們點(diǎn)擊轉(zhuǎn)賬時(shí),form表單中只要添加了{(lán)%csrf_token%},頁面就會(huì)自動(dòng)添加個(gè)隱藏的input標(biāo)簽,每次請求得到的的value值都不相同
只要手動(dòng)改下這個(gè)隱藏的input里面的value值,再提交數(shù)據(jù)就會(huì)forbidden。這個(gè)值只有是后臺(tái)給的才能通過鑒權(quán)
點(diǎn)擊轉(zhuǎn)賬,校驗(yàn)失敗,數(shù)據(jù)提交不成功
這樣,第三方請求在提交表單時(shí),就算猜到csrf_token的變量名,也無法猜測到服務(wù)器傳來的值,所以,就可以防范csrf攻擊
總結(jié)
簡單總結(jié)一下本文flask中CSRF攻擊的防護(hù)策略:文章來源:http://www.zghlxwxcb.cn/news/detail-850808.html
自動(dòng)防護(hù)策略:同源檢測(Origin和Referer驗(yàn)證);
主動(dòng)防護(hù)策略:token驗(yàn)證以及配合SameSite設(shè)置;
為了更好的防御CSRF,最佳實(shí)踐應(yīng)該是結(jié)合上面總結(jié)的防御措施方式中的優(yōu)缺點(diǎn)來綜合考慮,結(jié)合當(dāng)前Web應(yīng)用程序自身的情況做合適的選擇,才能更好的預(yù)防CSRF的發(fā)生。
喜歡的朋友可以一鍵三連,flask高階用法持續(xù)更新中?。?!文章來源地址http://www.zghlxwxcb.cn/news/detail-850808.html
到了這里,關(guān)于【python】深入探討flask是如何預(yù)防CSRF攻擊的的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!