FlawOpen

flawopen.com/JavaScript 中的 SQL 注入/TypeORM

TypeORM QueryBuilder 能防止 SQL 注入吗?

参考指南
简短回答

绑定参数就像表单中标记好的值栏:TypeORM 单独发送该值,使其保持为数据而不是 SQL 指令。QueryBuilder 会绑定单独传入的命名参数。将输入插值进条件字符串会使其重新成为 SQL 文本。

不安全 — 将输入插值到 SQL
userRepo.createQueryBuilder("u")
  .where(`u.id = ${userId}`)
  .getOne()
加固 — 单独绑定值
userRepo.createQueryBuilder("u")
  .where("u.id = :id", { id: userId })
  .getOne()

绑定值;限制查询结构

QueryBuilder.where() 接受带命名占位符(如 :id)的条件,以及单独的参数对象。不同值应使用不同名称;TypeORM 提醒,重复使用名称可能覆盖先前的值。不要将用户输入插值进条件。dataSource.query() 等 raw 方法也支持驱动专用占位符,并可单独传值。参数绑定数据,不能代表表名、列名、排序方向或任意 SQL。将可选结构映射到应用内固定表达式。

如何审查 TypeORM 查询构造

rg -n '(\.where\(|\.query\(|\.sql)' --glob '*.ts' .

常见问题

TypeORM Repository 的 find 方法总是安全吗?

常规 find 选项会将值交给 TypeORM 构造查询,但仍需审查自定义运算符、raw SQL 表达式和应用拼接的字符串。参数化可防止语法注入,但不能授权记录访问,也不能验证值的业务含义。

参考资料

另请参阅 SQL 注入(CWE-89):原理与各编程语言的防护方法 — flawopen.com Django ORM 与 SQL Injection:安全写法 Doctrine ORM SQL 注入:安全查询实践 EF Core FromSqlRaw:安全参数化 SQL FastAPI SQL 注入:Pydantic 能防什么,不能防什么 GORM Raw SQL:防止 Go 中的 SQL 注入 转义引号足以防止 SQL Injection 吗?