pydantic本身不防sql注入,仅做数据解析与结构校验;真正防护依赖数据库层参数化查询,但它是第一道关键防线,可拦截非法类型、畸形格式、超长字段等可疑输入。

Pydantic 本身不防 SQL 注入,它只做数据解析和结构校验;真正防注入靠的是数据库层的参数化查询。但 Pydantic 是第一道关键防线——它能拦住非法类型、畸形格式、超长字段等“可疑输入”,避免这些数据被错误地拼进 SQL 语句里。
为什么不能只靠 Pydantic 防 SQL 注入
Pydantic 的 BaseModel 校验发生在请求体解析阶段,它不接触数据库,也不干预 SQL 构建逻辑。如果你在业务代码里写 f"SELECT * FROM users WHERE name = '{user.name}'",哪怕 user.name 已经通过 Pydantic 的 min_length=2 和 regex 校验,只要它含单引号或分号,照样可能触发注入。
- Pydantic 不过滤字符,只验证结构和类型
- 它无法识别“看似合法但语义恶意”的输入(如
O'Reilly或admin'--) - 校验通过 ≠ 可直接拼 SQL;必须配合 SQLAlchemy 的
bindparam或原生execute(..., params={...})
Pydantic + SQLAlchemy 参数化查询的最小安全组合
真正起作用的是:Pydantic 做输入清洗 + 类型约束 + 长度控制,再把干净变量传给 SQLAlchemy 的参数化接口。
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 用
str字段 +Field(max_length=50)限制用户名长度,防止超长 payload 绕过前端限制 - 对 ID 类路径参数,强制用
int或conint(gt=0),杜绝字符串型 ID 被用于WHERE id = '1 OR 1=1' - 查询时永远用命名参数:
session.execute(text("SELECT * FROM users WHERE email = :email"), {"email": user.email}) - 避免任何
format、%、f-string拼接 SQL 字符串
容易被忽略的校验盲区
开发者常以为邮箱字段加了 pattern 就万无一失,其实攻击者可利用校验宽松点绕过:
-
Field(pattern=r".+@.+\..+")太宽泛,允许test@test.com'; DROP TABLE users; -- -
Optional[str]字段若未设默认值,在 ORM 查询中可能变成None,导致WHERE name = NULL逻辑异常或全表扫描 - 嵌套模型里的列表字段(如
tags: List[str])若没限制长度,可能被塞入上千个恶意字符串,压垮数据库连接或触发慢查询 - 使用
json.loads()手动解析字段时,会跳过 Pydantic 校验——必须改用Json类型注解或自定义 validator
最危险的操作,是把 Pydantic 模型实例直接当成 dict 传给 **kwargs 拼 SQL。安全边界只存在于「校验后 → 参数化执行」这一窄带,中间多一步字符串拼接,整条链就失效。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










