查询中的 TypeORM、反引号与冒号
Posted
技术标签:
【中文标题】查询中的 TypeORM、反引号与冒号【英文标题】:TypeORM, Backticks vs. Colon in Query 【发布时间】:2021-10-25 03:31:16 【问题描述】:我一直在使用反引号编写查询
const firstUser = await connection
.getRepository(User)
.createQueryBuilder("user")
.where(`user.id = '$id'`)
.getOne();
但在typeorm
文档中,示例是用冒号编写的。
const firstUser = await connection
.getRepository(User)
.createQueryBuilder("user")
.where("user.id = :id", id: 1 )
.getOne();
所以我想知道使用反引号和冒号之间是否有任何区别。
任何见解都将不胜感激。
谢谢。
【问题讨论】:
后者(可能)使您的id
参数可以安全地在查询中使用,方法是使用参数绑定或至少转义任何坏字符。与往常一样,您可以通过reading the fantastic manual 找到更多信息
【参考方案1】:
不要使用字符串插值将值插入到 SQL 语句中
很抱歉大喊大叫,但这很重要。
阅读:https://en.wikipedia.org/wiki/SQL_injection 然后这个:https://xkcd.com/327/当你这样做时:
.where(`user.id = '$id'`)
然后先创建字符串,然后传递给where()
函数。这意味着如果id
是123
,那么它与:
.where(`user.id = '123'`)
这看起来不错。但是如果id
是123' OR 1=1--'
会怎样
你现在明白了:
.where(`user.id = '123' OR 1=1--'`) // Now returns ALL users!
这叫SQL injection,这是一个很大的安全问题。这是非常非常糟糕的。攻击者可能会更改您的查询并访问他们不应访问的数据,或更改记录以授予自己管理员访问权限,或其他各种非常糟糕的事情。它非常接近授予每个人对您的数据库的完全读/写访问权限。
这让我们想到了这一点:
.where("user.id = :id", id: 1 )
为了解决这个问题,您要求 TypeORM 为您输入值,这会正确转义攻击者可能添加的任何值,因此输入没有可执行指令。
如果id
是邪恶的,那么它会变成这样的东西:
.where(`user.id = '123\' OR 1=1--'`) // note the backslash
// (actual query may vary based on different databases)
这里 TypeORM 通过转义攻击者插入的右引号来确保将 id 作为值处理的转义。这样可以安全地获取用户提供的值并在查询中使用它们。
总之,绝不将用户提供的值直接插入到查询中(实际上应该是所有值,为了安全起见),并且总是使用查询参数来确保值已正确缩放。
【讨论】:
感谢您的好意,我今天又学到了一件事。赞一个! 我差点把整张桌子都掉了。以上是关于查询中的 TypeORM、反引号与冒号的主要内容,如果未能解决你的问题,请参考以下文章