在 Python Web 开发领域,Flask 与 Django 凭借简洁高效、生态丰富的优势,成为中小企业、个人开发者搭建网站、API 服务的首选框架。但随着网络攻击手段不断升级,SQL 注入、XSS 跨站脚本这两大 OWASP Top10 高危漏洞,依然是 Python Web 应用最常遭遇的安全威胁。很多开发者只关注功能实现,忽略了安全加固,导致项目上线后面临数据泄露、数据库被篡改、用户会话劫持等风险。

本文结合多年 Python Web 开发与安全加固实战经验,整理出7 个可直接落地的安全技巧,覆盖 Flask 与 Django 双框架,从数据库操作、前端渲染、输入校验、配置加固等维度,彻底防范 SQL 注入与 XSS 攻击,帮助开发者快速提升项目安全等级,让 Web 应用更稳定、更安全。

一、杜绝字符串拼接,用参数化查询筑牢 SQL 注入防线

SQL 注入是最常见的攻击方式,攻击者通过在输入框、URL 参数中插入恶意 SQL 语句,拼接进后端查询逻辑,实现绕过登录、删除数据表、窃取全量数据等操作。90% 的 SQL 注入漏洞,都源于开发者直接用字符串拼接 SQL 语句

在 Flask 开发中,很多新手习惯用 SQLAlchemy 拼接原生 SQL,或直接用 Python 的 f-string 格式化查询语句,这是极大的安全隐患。正确做法是全程使用参数化查询,将 SQL 语句与用户输入参数分离,数据库会自动对参数进行转义,杜绝注入可能。

python

运行

# Flask 危险写法:字符串拼接,极易被SQL注入
def get_user_unsafe(username):
    sql = f"SELECT * FROM users WHERE username = '{username}'"
    return db.session.execute(sql).fetchone()

# Flask 安全写法:参数化查询,SQLAlchemy自动转义
def get_user_safe(username):
    sql = text("SELECT * FROM users WHERE username = :username")
    return db.session.execute(sql, {"username": username}).fetchone()

Django 框架自带的 ORM 天然支持参数化查询,无需手动处理,直接使用 filter、exclude 等查询方法,就能自动防范 SQL 注入。只有在必须使用原生 SQL 时,才需要手动绑定参数,避免字符串拼接。

python

运行

# Django 安全写法:原生SQL参数绑定
from django.db import connection
def get_user_django(username):
    with connection.cursor() as cursor:
        cursor.execute("SELECT * FROM users WHERE username = %s", [username])
        return cursor.fetchone()

核心原则:永远不要将用户输入直接拼接到 SQL 语句中,优先使用框架 ORM,原生 SQL 必用参数化。

二、开启模板自动转义,从源头阻断 XSS 攻击

XSS 跨站脚本攻击,是攻击者在网页中注入恶意 JavaScript 代码,当用户访问时自动执行,实现窃取 Cookie、劫持会话、篡改页面内容等目的。XSS 分为存储型、反射型、DOM 型,其中存储型 XSS 危害最大,漏洞多源于前端渲染用户输入时未做转义。

Flask 与 Django 的模板引擎都支持自动转义功能,会将用户输入中的>&"'等特殊字符转换为 HTML 实体,让浏览器将其当作普通文本渲染,而非执行代码。

Flask 基于 Jinja2 模板引擎,默认开启自动转义,无需额外配置,直接渲染变量即可:

html

预览

渲染:自动转义用户输入 -->
_input_content }}```

Django模板引擎同样默认开启自动转义,渲染变量时会自动处理特殊字符,只有在明确需要渲染HTML时,才使用`safe`过滤器,且必须提前对内容做净化处理。

```html
渲染:默认自动转义 -->
 }}需要注意的是,**不要随意关闭自动转义**,也不要滥用`safe`、`mark_safe`等方法,除非已对用户输入做了严格的HTML净化。

## 三、用bleach库净化富文本,应对自定义HTML输入
在评论区、文章编辑器、用户简介等场景,需要允许用户输入少量HTML标签(如``自动转义会影响展示效果,单纯关闭转义又会引发XSS漏洞。这时需要用**专门的HTML净化库**,只保留安全标签,过滤恶意脚本与危险属性。

推荐使用Python的`bleach`库,支持自定义白名单标签、属性,自动删除`、`onclick`、`javascript:`等危险内容,Flask与Django均可通用。

```python
import bleach
# 定义安全标签白名单
ALLOWED_TAGS = ['p', 'b', 'i', 'u', 'a', 'br']
ALLOWED_ATTRS = {'a': ['href', 'title']}

# 净化用户输入的富文本内容
def sanitize_html(content):
    return bleach.clean(content, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRS)

将净化后的内容存入数据库,再渲染到页面,既能保证展示效果,又能彻底阻断 XSS 攻击,这是处理富文本场景的标准安全方案。

四、严格校验用户输入,实现全链路输入过滤

安全防护的核心原则是永远不信任用户输入,无论前端是否做了校验,后端都必须对所有输入数据做严格的格式、长度、类型校验,从入口处拦截恶意数据。

针对 Flask 项目,可使用WTForms做表单校验;Django 自带Form表单校验组件,也可结合Pydantic做 API 参数校验,限制输入内容的长度、字符类型、格式规范。

python

运行

# Flask WTForms 输入校验示例
from wtforms import StringField, validators
class UserForm(FlaskForm):
    username = StringField('用户名', validators=[
        validators.Length(min=3, max=20),  # 限制长度
        validators.Regexp(r'^[a-zA-Z0-9_]+$')  # 限制字符类型
    ])

同时,对 URL 参数、请求头、JSON 数据等所有用户可控的输入,都要做校验,避免攻击者通过非常规入口提交恶意数据。输入校验是安全加固的第一道防线,也是最基础、最有效的手段。

五、配置安全响应头,强化浏览器安全防护

除了代码层面的防护,还可以通过配置HTTP 安全响应头,让浏览器主动拦截 XSS、点击劫持等攻击,形成双层防护。Flask 与 Django 均可通过中间件或响应对象添加安全头。

核心安全头配置:

  1. Content-Security-Policy(CSP):限制页面资源加载来源,禁止执行未知脚本,从浏览器层面阻断 XSS;
  2. X-Content-Type-Options:禁止浏览器 MIME 类型嗅探,避免被伪装文件攻击;
  3. X-Frame-Options:防止页面被嵌套进 iframe,防范点击劫持;
  4. X-XSS-Protection:开启浏览器内置 XSS 防护。

Flask 可通过Flask-Talisman扩展快速配置,Django 直接在中间件中添加即可,配置后无需修改业务代码,就能大幅提升安全等级。

六、禁用 DEBUG 模式,隐藏敏感报错信息

开发环境中开启 DEBUG 模式,能快速定位代码错误,但生产环境必须禁用 DEBUG。一旦开启,攻击者可通过构造恶意请求,触发报错页面,泄露项目路径、数据库配置、代码逻辑等敏感信息,为 SQL 注入、XSS 攻击提供突破口。

Flask 生产环境配置:

python

运行

# Flask 生产环境禁用DEBUG
app.config['DEBUG'] = False
app.config['ENV'] = 'production'

Django 生产环境配置:

python

运行

# Django 生产环境安全配置
DEBUG = False
ALLOWED_HOSTS = ['你的域名']  # 限制访问域名
SECRET_KEY = '高强度随机密钥'  # 避免使用简单密钥

同时,生产环境要统一处理异常,返回友好的错误提示,而非原生报错信息,避免敏感数据泄露。

七、定期扫描依赖漏洞,保持框架与库最新版本

Flask、Django 框架及第三方依赖库,可能存在未知安全漏洞,攻击者会利用公开漏洞发起攻击。开发者需要定期扫描项目依赖,及时更新框架与库版本,修复已知漏洞。

可使用safety工具扫描依赖漏洞,pip audit检查过时库,同时关注 Flask、Django 官方安全公告,及时升级到最新稳定版。

bash

运行

# 安装safety扫描依赖漏洞
pip install safety
safety check

另外,避免使用废弃、不再维护的第三方库,选择官方推荐、社区活跃的组件,减少安全隐患。

总结

SQL 注入与 XSS 攻击看似复杂,实则只要掌握正确的加固方法,就能轻松防范。本文分享的 7 个 Python 安全技巧,从数据库操作、前端渲染、输入校验、配置加固、依赖管理全维度覆盖,Flask 与 Django 项目均可直接落地。

Web 安全不是一次性操作,而是持续优化的过程。开发者要养成安全编码习惯,遵循 “最小权限、不信任输入、多层防护” 的原则,在开发阶段就融入安全意识,才能从根源上杜绝漏洞。希望这些实战技巧能帮助广大 Python 开发者,打造更安全、更可靠的 Web 应用,守护项目与用户数据安全。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐