《Python實戰進階》No 10:基于Flask案例的Web 安全性:防止 SQL 注入、XSS 和 CSRF 攻擊

第10集:Web 安全性:防止 SQL 注入、XSS 和 CSRF 攻擊

在現代 Web 開發中,安全性是至關重要的。無論是用戶數據的保護,還是系統穩定性的維護,開發者都需要對常見的 Web 安全威脅有深刻的理解,并采取有效的防護措施。本集聚焦于三種最常見的 Web 安全威脅:SQL 注入、跨站腳本攻擊(XSS) 和跨站請求偽造(CSRF),通過一個加固前帶有漏洞的代碼案例,和一個加固后補全漏洞的代碼案例,幫助讀者深刻認識如何在 Python Web 應用中防范這些攻擊。


在這里插入圖片描述

一、SQL 注入攻擊及其防御

1. 什么是 SQL 注入?
SQL 注入是一種利用應用程序未能正確過濾用戶輸入的漏洞,通過注入惡意 SQL 查詢語句來操縱數據庫的行為。攻擊者可以借此獲取敏感信息、篡改數據,甚至刪除整個數據庫。

2. 防御 SQL 注入的關鍵策略

  • 參數化查詢:這是最基礎也是最有效的防范措施。參數化查詢將用戶輸入的數據與 SQL 命令分開,避免了惡意輸入被解釋為 SQL 指令。
    # 使用 SQLAlchemy 的參數化查詢示例
    from sqlalchemy import text
    query = text("SELECT * FROM users WHERE username = :username")
    result = db.execute(query, {"username": user_input})
    
  • 最小權限原則:限制數據庫用戶的權限,確保即使攻擊者成功注入 SQL 語句,也無法對數據庫造成嚴重破壞。
  • 輸入驗證和過濾:對用戶輸入進行嚴格的驗證,確保其符合預期格式和類型。
  • 使用 Web 應用防火墻(WAF):部署 WAF 可以檢測并阻止潛在的 SQL 注入攻擊。

二、跨站腳本攻擊(XSS)及其防御

1. 什么是 XSS 攻擊?
XSS(Cross-Site Scripting)是指攻擊者通過在 Web 頁面中插入惡意腳本代碼,當其他用戶瀏覽該頁面時,惡意腳本會在用戶的瀏覽器上執行,從而竊取用戶信息或實施其他惡意行為。

2. XSS 的常見類型

  • 存儲型 XSS:惡意腳本被永久存儲在目標服務器上(如數據庫),并通過正常頁面加載傳播給其他用戶。
  • 反射型 XSS:惡意腳本通過 URL 參數傳遞,并在頁面加載時直接執行。
  • DOM 型 XSS:攻擊發生在客戶端,不涉及服務器端的處理。

3. 防御 XSS 的關鍵策略

  • 輸入驗證:確保用戶輸入的內容符合預期格式,并拒絕任何包含非法字符的輸入。
  • 輸出編碼:在將用戶輸入的內容返回到前端時,對其進行 HTML 編碼,防止惡意腳本被執行。
    # 使用 Django 的 escape 函數對輸出進行編碼
    from django.utils.html import escape
    safe_output = escape(user_input)
    
  • 啟用內容安全策略(CSP):通過 HTTP 頭部設置 CSP,限制頁面中可以加載的資源來源,減少 XSS 攻擊的可能性。

三、跨站請求偽造(CSRF)及其防御

1. 什么是 CSRF 攻擊?
CSRF(Cross-Site Request Forgery)是指攻擊者誘導用戶訪問惡意網站,然后利用用戶的已登錄狀態向目標網站發起未經授權的請求。例如,攻擊者可能通過偽造表單提交操作,導致用戶無意中修改賬戶信息或轉賬資金。

2. 防御 CSRF 的關鍵策略

  • 使用 CSRF Token:在表單中嵌入一個隨機生成的 Token,并在服務器端驗證該 Token 是否合法。這樣可以確保請求是由合法用戶發起的。
    # Flask-WTF 自動生成 CSRF Token 示例
    from flask_wtf.csrf import CSRFProtect
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'your_secret_key'
    csrf = CSRFProtect(app)
    
  • 檢查 Referer 頭部:驗證請求是否來自合法的源地址。
  • SameSite Cookie 屬性:通過設置 Cookie 的 SameSite 屬性為 StrictLax,限制 Cookie 在跨站請求中的發送。

四、總結與最佳實踐

以下是一個基于 Flask 的完整案例,綜合運用 SQL 注入、XSS 和 CSRF 的防御技術,并結合知識庫中的參考資料進行說明。


案例:用戶注冊與登錄系統(安全加固版)

1. 項目結構
myapp/
├── app.py          # 主程序
├── models.py       # 數據庫模型
├── templates/
│   ├── register.html
│   ├── login.html
│   └── profile.html
└── requirements.txt

2. 核心代碼實現

2.1 防止 SQL 注入
使用 SQLAlchemy 的參數化查詢,避免直接拼接 SQL 語句。

# models.py
from flask_sqlalchemy import SQLAlchemydb = SQLAlchemy()class User(db.Model):id = db.Column(db.Integer, primary_key=True)username = db.Column(db.String(80), unique=True, nullable=False)password = db.Column(db.String(120), nullable=False)

錯誤示例(直接拼接 SQL):

# 危險!容易被 SQL 注入
query = f"SELECT * FROM users WHERE username = '{user_input}'"

正確示例(參數化查詢):

# app.py
from models import User@app.route('/login', methods=['POST'])
def login():username = request.form['username']user = User.query.filter_by(username=username).first()  # 安全查詢# ...后續驗證邏輯

2.2 防止 XSS 攻擊
在模板中自動轉義用戶輸入。

<!-- templates/profile.html -->
<!-- 使用 Jinja2 的自動轉義功能 -->
<p>歡迎, {{ user.username | safe }}!</p>  <!-- 錯誤:禁用轉義會引發 XSS -->
<p>歡迎, {{ user.username }}!</p>         <!-- 正確:默認自動轉義 -->

手動防御:在視圖函數中對輸出編碼:

from markupsafe import escape@app.route('/profile/<username>')
def profile(username):safe_username = escape(username)  # 轉義特殊字符return render_template('profile.html', username=safe_username)

2.3 防止 CSRF 攻擊
使用 Flask-WTF 生成和驗證 CSRF Token。

# app.py
from flask_wtf.csrf import CSRFProtectapp = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
csrf = CSRFProtect(app)  # 啟用全局 CSRF 保護@app.route('/register', methods=['GET', 'POST'])
def register():form = RegistrationForm()  # 繼承自 FlaskFormif form.validate_on_submit():# 處理注冊邏輯return render_template('register.html', form=form)
<!-- templates/register.html -->
<form method="POST">{{ form.hidden_tag() }}  <!-- 自動生成 CSRF Token -->{{ form.username.label }} {{ form.username() }}{{ form.password.label }} {{ form.password() }}<input type="submit" value="注冊">
</form>

3. 綜合防御策略
  1. 輸入驗證:使用 WTForms 對用戶名和密碼格式進行校驗。

    from wtforms import StringField, PasswordField
    from wtforms.validators import DataRequired, Lengthclass RegistrationForm(FlaskForm):username = StringField('用戶名', validators=[DataRequired(), Length(max=80)])password = PasswordField('密碼', validators=[DataRequired(), Length(min=8)])
    
  2. 內容安全策略(CSP)
    通過 HTTP 頭限制腳本來源:

    @app.after_request
    def set_csp(response):response.headers['Content-Security-Policy'] = "default-src 'self'; script-src 'self'"return response
    
  3. SameSite Cookie 屬性
    防止跨站請求攜帶 Cookie:

    app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'
    

4. 測試與驗證
  • SQL 注入測試:嘗試輸入 ' OR 1=1--,驗證是否無法繞過登錄。
  • XSS 測試:輸入 <script>alert('xss')</script>,驗證是否被轉義。
  • CSRF 測試:使用 Postman 直接提交表單,驗證是否因缺少 Token 被攔截。

以下通過兩套正反代碼及攻擊代碼示例,讓讀者更深刻認識本文內容。

login.html 代碼

<!-- templates/login.html -->
<!DOCTYPE html>
<html>
<head><title>登錄</title>
</head>
<body><h2>用戶登錄</h2><form method="POST">{{ form.hidden_tag() }}  <!-- CSRF Token --><div>{{ form.username.label }}<br>{{ form.username(size=32) }}</div><div>{{ form.password.label }}<br>{{ form.password(size=32) }}</div><div><input type="submit" value="登錄"></div></form>
</body>
</html>

完整代碼示意:無防護措施的代碼及攻擊示例

1.1 存在漏洞的代碼(SQL 注入 + XSS)
# app.py(錯誤示例)
from flask import Flask, request, render_template_stringapp = Flask(__name__)# 模擬用戶數據庫
users = {"admin": "admin123"
}@app.route('/login', methods=['GET', 'POST'])
def login():if request.method == 'POST':username = request.form['username']password = request.form['password']# 危險!直接拼接 SQL 查詢(假設使用 SQLite)query = f"SELECT * FROM users WHERE username = '{username}' AND password = '{password}'"# 模擬查詢結果(實際場景中可能直接執行 SQL)if username in users and users[username] == password:return f"歡迎,{username}!"  # 未轉義輸出,存在 XSSelse:return "登錄失敗"return render_template_string('''<form method="POST">用戶名:<input type="text" name="username"><br>密碼:<input type="password" name="password"><br><input type="submit" value="登錄"></form>''')
1.2 攻擊示例
  • SQL 注入攻擊
    輸入用戶名為 admin’ OR ‘1’ = '1,密碼任意(假設為 a_random_password),此時完美繞過驗證并執行了查詢語句:

    SELECT * FROM users WHERE username = 'admin'  OR  '1' = '1' AND password = 'a_random_password'
    

    后果:攻擊者無需密碼即可登錄任意賬戶。

  • XSS 攻擊
    輸入用戶名為 <script>alert('XSS')</script>,密碼任意:

    return f"歡迎,{username}!"  # 未轉義輸出
    

    后果:惡意腳本在用戶瀏覽器執行,竊取 Cookie 或重定向到釣魚網站。


完整代碼示意:有防護措施的代碼及成功防御

2.1 安全加固的代碼
# app.py(正確示例)
from flask import Flask, request, render_template
from flask_wtf.csrf import CSRFProtect
from wtforms import StringField, PasswordField, validators
from werkzeug.security import check_password_hash
from models import User  # 假設使用 SQLAlchemy 模型app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
csrf = CSRFProtect(app)  # 啟用 CSRF 保護class LoginForm(FlaskForm):username = StringField('用戶名', [validators.DataRequired()])password = PasswordField('密碼', [validators.DataRequired()])@app.route('/login', methods=['GET', 'POST'])
def login():form = LoginForm()if form.validate_on_submit():username = form.username.datapassword = form.password.data# 使用參數化查詢防止 SQL 注入user = User.query.filter_by(username=username).first()if user and check_password_hash(user.password, password):return render_template('welcome.html', username=escape(username))  # 轉義輸出else:return "登錄失敗"return render_template('login.html', form=form)
2.2 防御效果
  • SQL 注入防御
    輸入 admin’ OR ‘1’ = '1 會被參數化查詢自動轉義為字符串,無法破壞 SQL 語法。

    SELECT * FROM users WHERE username = ''admin'  OR  '1' = '1''  -- 無效查詢
    
  • XSS 防御
    輸入 <script>alert('XSS')</script> 會被 Jinja2 自動轉義為:

    &lt;script&gt;alert('XSS')&lt;/script&gt;
    

    瀏覽器不會執行腳本,僅顯示純文本 。

  • CSRF 防御
    未攜帶合法 Token 的請求會被 Flask-WTF 攔截,返回 403 錯誤 。


總結

攻擊類型無防護后果防護措施防護效果
SQL 注入繞過登錄驗證參數化查詢攻擊失效
XSS竊取用戶會話輸出轉義 + CSP腳本被轉義
CSRF偽造請求操作CSRF Token請求被攔截
5. 總結

通過本案例,我們實現了:

  1. 參數化查詢(SQLAlchemy)防范 SQL 注入。
  2. 模板轉義 + CSP 防范 XSS。
  3. CSRF Token + SameSite Cookie 防范 CSRF。

為了構建一個安全的 Web 應用,開發者需要從多個層面入手,結合技術手段和開發習慣來防范上述攻擊:

  1. 代碼層面:始終使用參數化查詢、輸入驗證和輸出編碼,避免直接拼接用戶輸入。
  2. 架構層面:采用最小權限原則,限制數據庫用戶權限,并部署 WAF 等安全工具。
  3. 框架支持:利用現代 Web 框架(如 Django、Flask)內置的安全機制,例如 CSRF Token 和 XSS 防護。
  4. 定期測試:通過滲透測試和代碼審計,發現并修復潛在的安全漏洞[[4]]。

安全性是一個持續改進的過程。隨著攻擊手段的不斷演變,開發者也需要保持警惕,及時更新知識和技術,確保應用的安全性。


五、擴展閱讀與參考資料

參考資料

  • Flask 綜合案例開發流程
  • REST API 安全設計
  • CSRF 防御最佳實踐
  • 深入理解 SQL 注入:原理、攻擊流程與防御措施 - Freebuf
  • Web 安全頭號大敵 XSS 漏洞解決最佳實踐 - 騰訊云
  • 防止 SQL 注入的四種方案 - CSDN博客

通過本集的學習,相信你已經掌握了如何在 Python Web 應用中防范 SQL 注入、XSS 和 CSRF 攻擊的核心技能。下一集我們將進入微服務架構設計的世界,探索如何用 Python 構建高效、可擴展的分布式系統。敬請期待!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/897017.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/897017.shtml
英文地址,請注明出處:http://en.pswp.cn/news/897017.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【大數據分析 | 深度學習】在Hadoop上實現分布式深度學習

【作者主頁】Francek Chen 【專欄介紹】 ? ? ?智能大數據分析 ? ? ? 智能大數據分析是指利用先進的技術和算法對大規模數據進行深入分析和挖掘&#xff0c;以提取有價值的信息和洞察。它結合了大數據技術、人工智能&#xff08;AI&#xff09;、機器學習&#xff08;ML&a…

盛鉑科技SCP4000射頻微波功率計與SPP5000系列脈沖峰值 USB功率計 區別

在射頻&#xff08;RF&#xff09;和微波測試領域&#xff0c;快速、精準的功率測量是確保通信系統、雷達、衛星設備等高性能運行的核心需求。無論是連續波&#xff08;CW&#xff09;信號的穩定性測試&#xff0c;還是脈沖信號的瞬態功率分析&#xff0c;工程師都需要輕量化、…

自學微信小程序的第十三天

DAY13 1、使用map組件在頁面中創建地圖后&#xff0c;若想在JS文件中對地圖進行控制&#xff0c;需要通過地圖API來完成。先通過wx.createMapContext()方法創建MapContext&#xff08;Map上下文&#xff09;實例&#xff0c;然后通過該實例的相關方法來操作map組件。 const m…

深入解析 C# 中的泛型:概念、用法與最佳實踐

C# 中的 泛型&#xff08;Generics&#xff09; 是一種強大的編程特性&#xff0c;允許開發者在不預先指定具體數據類型的情況下編寫代碼。通過泛型&#xff0c;C# 能夠讓我們編寫更靈活、可重用、類型安全且性能優良的代碼。泛型廣泛應用于類、方法、接口、委托、集合等多個方…

H5DS編輯器是如何讓企業快速構建動態頁面

H5DS編輯器核心亮點&#xff1a; 1.拖拽式操作&#xff0c;小白友好&#xff1a;無需設計與代碼基礎&#xff01;通過簡單拖拽元素、調整文字和動畫&#xff0c;即可生成交互式H5頁面。內置海量模板和素材庫&#xff0c;支持自定義設計風格&#xff0c;輕松適配企業品牌需求。…

Unity ECS與MonoBehaviour混合架構開發實踐指南

一、混合架構設計背景 1. 技術定位差異 ECS&#xff08;Entity Component System&#xff09;&#xff1a;面向數據設計&#xff08;DOD&#xff09;&#xff0c;適用于大規模實體計算&#xff08;如10萬單位戰斗&#xff09; MonoBehaviour&#xff1a;面向對象設計&#xf…

[項目]基于FreeRTOS的STM32四軸飛行器: 三.電源控制

基于FreeRTOS的STM32四軸飛行器: 三.電源控制 一.IP5305T芯片手冊二.電源控制任務 一.IP5305T芯片手冊 注意該芯片低功耗特性&#xff0c;為防止進入待機&#xff0c;每隔一段時間發送一個電平。 官方提供的芯片外圍電路設計圖&#xff1a; 電氣特性&#xff1a; 當負載電流持…

java環境部署

java環境部署 一、準備工作 jrejdkeclipse jdk下載&#xff1a;21和1.8-----官網&#xff1a;Oracle&#xff1a;Java 下載 |神諭 該處選擇要依據自身的系統類型選擇下載 idea的下載安裝&#xff1a;IntelliJ IDEA | Other Versions 二、安裝 三、環境配置 四、使用 五、i…

微服務通信:用gRPC + Protobuf 構建高效API

引言 在微服務架構中&#xff0c;服務之間的通信是系統設計的核心問題之一。傳統的RESTful API雖然簡單易用&#xff0c;但在性能、類型安全和代碼生成等方面存在一定的局限性。gRPC作為一種高性能、跨語言的RPC框架&#xff0c;結合Protobuf&#xff08;Protocol Buffers&…

使用 Docker 和 Nginx 高效部署 Web 服務(適用于慈云數據云服務器)

前言 在現代 Web 服務部署中&#xff0c;Docker 和 Nginx 的結合是一種高效、靈活且可擴展的解決方案。 Docker 使應用程序及其依賴項封裝到一個獨立的容器中&#xff0c;確保一致性&#xff0c;并簡化部署過程。Nginx 作為高性能 Web 服務器和反向代理&#xff0c;能夠高效處…

C 語言數據結構(一):時/空間復制度

目錄 一、前言 1. 什么是數據結構 2. 什么是算法 二、時 / 空間復雜度 1. 算法效率 2. 時間復雜度 2.1 時間復雜度的概念 2.2 大 O 的漸進表示法 2.3 常見的計算時間復雜度的例子 2.3.1 實例 1 2.3.2 實例 2 2.3.3 實例 3 2.3.4 實例 4 2.3.5 實例 5 &#xff1a…

一文讀懂Redis分布式鎖

引言 在當今互聯網時代&#xff0c;分布式系統已成為大規模應用的主流架構。然而&#xff0c;這種架構中多個服務同時對共享資源的操作可能導致并發問題&#xff0c;如數據不一致和資源爭用。有效管理這些并發訪問&#xff0c;確保共享資源的安全性顯得尤為重要。 分布式鎖作…

23種設計模式一覽【設計模式】

文章目錄 前言一、創建型模式&#xff08;Creational Patterns&#xff09;二、結構型模式&#xff08;Structural Patterns&#xff09;三、行為型模式&#xff08;Behavioral Patterns&#xff09; 前言 設計模式是軟件工程中用來解決特定問題的一組解決方案。它們是經過驗證…

極狐GitLab 17.9 正式發布,40+ DevSecOps 重點功能解讀【三】

GitLab 是一個全球知名的一體化 DevOps 平臺&#xff0c;很多人都通過私有化部署 GitLab 來進行源代碼托管。極狐GitLab 是 GitLab 在中國的發行版&#xff0c;專門為中國程序員服務。可以一鍵式部署極狐GitLab。 學習極狐GitLab 的相關資料&#xff1a; 極狐GitLab 官網極狐…

elk的相關的基礎

以下是關于ELK&#xff08;Elasticsearch, Logstash, Kibana&#xff09;的200個基礎問題及其答案&#xff0c;涵蓋了ELK的核心概念、組件、配置、使用場景、優化等方面。 ?Elasticsearch 基礎 ?**什么是Elasticsearch&#xff1f;**? 答&#xff1a;Elasticsearch是一個分…

Beyond Compare for mac v5.0.6.30713 文件對比利器 支持M、Intel芯片

Mac毒搜集到的Beyond Compare是一套超級的文件及文件夾(目錄)的比較工具&#xff0c;不僅可以快速比較出兩個目錄的不同&#xff0c;還可以比較每個文件的內容&#xff0c;而且可以任意顯示比較結果。 應用介紹 程序內建了文件瀏覽器&#xff0c;方便您對文件、文件夾、壓縮包…

ProfibusDP主站轉ModbusTCP網關如何進行數據互換

ProfibusDP主站轉ModbusTCP網關如何進行數據互換 在現代工業自動化領域&#xff0c;通信協議的多樣性和復雜性不斷增加。Profibus DP作為一種經典的現場總線標準&#xff0c;廣泛應用于工業控制網絡中&#xff1b;而Modbus TCP作為基于以太網的通信協議&#xff0c;因其簡單易…

python代碼注釋方式

在 Python 中&#xff0c;注釋是用于解釋代碼、提高代碼可讀性和可維護性的重要工具。Python 支持兩種主要的注釋方式&#xff1a;單行注釋和多行注釋。此外&#xff0c;Python 還支持文檔字符串&#xff08;docstrings&#xff09;&#xff0c;用于為模塊、函數、類和方法提供…

【雜談】信創電腦華為w515(統信系統)登錄鎖定及忘記密碼處理

華為w515麒麟芯片版&#xff0c;還有非麒麟芯片版本&#xff0c;是一款信創電腦&#xff0c;一般安裝的UOS系統。 準備一個空U盤&#xff0c;先下載鏡像文件及啟動盤制作工具&#xff0c;連接如下&#xff1a; 百度網盤 請輸入提取碼 http://livecd.uostools.com/img/apps/l…

數據結構秘籍(四) 堆 (詳細包含用途、分類、存儲、操作等)

1 引言 什么是堆&#xff1f; 堆是一種滿足以下條件的樹&#xff1a;&#xff08;樹這一篇可以參考我的文章數據結構秘籍&#xff08;三&#xff09;樹 &#xff08;含二叉樹的分類、存儲和定義&#xff09;-CSDN博客&#xff09; 堆中的每一個結點值都大于等于&#xff08…