查询中的 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()函数。这意味着如果id123,那么它与:

.where(`user.id = '123'`)

这看起来不错。但是如果id123' 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、反引号与冒号的主要内容,如果未能解决你的问题,请参考以下文章

单引号字符串与双引号字符串中的反斜杠

在休眠中将“反引号”添加到列名

Hive SQL中关于反引号的使用

Linux Shell 中的反引号,单引号,双引号

shell中对于单引号,双引号和反引号的处理方式

为啥反引号在 PDO 查询中失败? [复制]