第三方库本身不直接引入sql注入漏洞,但若封装拼接sql逻辑(如sqlalchemy.text()、sequelize.query()、mybatis ${}等),且调用不安全api,则存在真实风险;静态扫描工具无法发现此类“行为型”风险,必须人工审计原生sql调用点并确认是否使用参数化。

第三方库本身不直接引入 SQL 注入漏洞,但若它封装了拼接 SQL 的逻辑(如旧版 ORM 插件、数据库工具类),且你调用了其不安全的 API,风险就真实存在。单纯扫 requirements.txt 或 package.json 只能发现已知 CVE,漏掉这类“行为型”风险。
哪些第三方库要重点盯住原生 SQL 接口
不是所有库都危险,但以下类型一旦被使用,必须人工确认是否走参数化:
-
sqlalchemy.text()、sequelize.query()、MyBatis ${}(注意是${},不是#{})——这些明确允许字符串拼接 - 旧版
peewee(.raw()方法)、pydal(executesql())——文档里常写“use with caution” - 自定义封装的
db.execute(sql, params)工具函数,如果sql参数来自用户输入或配置文件,立刻标记为高危
用 safety 或 pip-audit 扫不出这类问题,怎么办
静态扫描工具只比对已知漏洞数据库(NVD),而拼接 SQL 是代码逻辑问题,不属于 CVE 范畴。必须结合代码审计:
- 在项目根目录执行:
grep -r "\.text(" --include="*.py" .和grep -r "query(" --include="*.js" .,定位所有原生 SQL 调用点 - 检查调用处:传入的 SQL 字符串是否含
f"SELECT ... {user_input}"、"WHERE id = " + req.args.get("id")等模式 - 对 Java 项目,重点搜
createNativeQuery(、executeUpdate(,再看参数是否经setParameter()处理
为什么更新库版本有时反而放大风险
某些库在新版本中新增了原生 SQL 方法(比如 sqlmodel 0.24+ 加了 session.exec()),但文档没强调风险,开发者误以为“新即安全”:
- 升级前查 CHANGELOG,关键词搜
native、raw、unescaped - 用
git grep -n "session.exec(" HEAD~10..HEAD看是否本次升级引入了新调用点 - CI 中加一条检查:
! grep -r "\.exec(" --include="*.py" . | grep -v "test_",阻断未测试的原生执行
真正难防的不是老库,而是新库里悄悄混进来的字符串拼接调用——它不会报 CVE,也不会被 safety check 拦住,只能靠人盯住每一处 .text()、.query()、${} 的上下文。











