You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQLAlchemy如何安全为where/order_by传多条件防范SQL注入

SQLAlchemy动态多条件查询防注入改造方案

你原有代码的SQL注入风险来自直接用f-string把用户输入拼接进text()构造的SQL片段,用户传入的恶意参数会被直接编译为SQL语句执行,必须彻底替换这种写法。

核心安全原则

  • 所有用户传入的查询参数值,禁止直接拼接进SQL字符串,必须通过SQLAlchemy的原生表达式构造,底层会自动走数据库预编译参数绑定,完全规避注入风险
  • 排序字段、排序方向属于SQL语法结构,无法通过参数绑定处理,必须做严格白名单校验,仅允许提前定义的合法值传入

具体改造实现

1. 基础改造(固定过滤、排序规则场景)

如果你当前的过滤、排序字段是固定的(即city对应等值过滤+升序、zip对应大于过滤+降序、serial对应IN过滤+升序,不需要用户自定义排序规则),直接用模型字段构造表达式即可,不需要使用text():

from sqlalchemy import select, and_, asc, desc
# 替换为你实际的模型导入路径
from your_models import Archive, Backup

filters = []
sorts = []

if 'city' in query:
    city_val = query['city']
    # 模型字段表达式自动做参数绑定,无注入风险
    filters.append(Archive.city == city_val)
    # 注:原代码此处写了等值判断属于笔误,排序逻辑应为指定字段+排序方向
    sorts.append(asc(Archive.city))

if 'zip' in query:
    zip_val = query['zip']
    filters.append(Archive.zip > zip_val)
    sorts.append(desc(Archive.zip))

if 'serial' in query:
    serial_val = query['serial']
    # 处理IN查询参数,兼容用户传入逗号分隔字符串、列表两种格式
    if not isinstance(serial_val, (list, tuple)):
        serial_val = [s.strip() for s in str(serial_val).split(',') if s.strip()]
    filters.append(Backup.serial.in_(serial_val))
    sorts.append(asc(Backup.serial))

with Session(engine) as session:
    stmt = select(Archive, Backup).join(Backup)
    if filters:
        stmt = stmt.where(and_(*filters))
    if sorts:
        stmt = stmt.order_by(*sorts)
    results = session.exec(stmt).all()

2. 扩展:支持用户动态指定排序规则

如果你需要允许用户通过URL参数自定义排序字段、排序方向,必须增加白名单校验,绝对不能直接使用用户传入的字段名/方向拼接语句:

# 提前定义合法字段、排序方向的映射白名单
ALLOWED_SORT_FIELDS = {
    "city": Archive.city,
    "zip": Archive.zip,
    "serial": Backup.serial
}
ALLOWED_SORT_DIR = {
    "asc": asc,
    "desc": desc
}

# 读取用户传入的排序参数,走白名单校验
user_sort_field = query.get("sort_by")
user_sort_dir = query.get("sort_order", "asc").lower()
if user_sort_field in ALLOWED_SORT_FIELDS and user_sort_dir in ALLOWED_SORT_DIR:
    sort_func = ALLOWED_SORT_DIR[user_sort_dir]
    sorts.append(sort_func(ALLOWED_SORT_FIELDS[user_sort_field]))

安全说明:上述写法中,所有用户传入的参数值都会被SQLAlchemy作为绑定参数传入数据库驱动,不会和SQL语句字符串做拼接,从根源上阻断SQL注入可能;涉及SQL结构的字段、排序方向全部经过白名单拦截,非法输入会被直接忽略,不存在注入漏洞。

内容的提问来源于stack exchange,提问作者johojojoj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 10:18:52