《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.mzph.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…