如何编写参数化的sql查询以防止SQL注入?

时间:2016-11-19 01:38:27

标签: javascript sql postgresql knex.js

我最初发现这是一个问题,当我尝试搜索前面带有主题标签的术语时,结果是SQL中的注释分隔符。搜索没有返回任何内容,因为它忽略了hashtag之后的#term。

所以现在我无法找到逃避用户输入的正确方法。在我看来,这既解决了标签问题,也解决了更大的问题,SQL注入。

以下是我正在使用的代码段:

function (term) {
  term = term.toLowerCase()
  return db('ticket')
    .select('*')
    .where(db.raw('lower(question)'), 'like', `%${term}%`)
    .orWhere(db.raw('lower(note)'), 'like', `%${term}%`)
    .orWhere(db.raw('lower(user_name)'), 'like', `%${term}%`)
}

我确实找到了thisthis SO文章似乎很接近,以及其他几件事。此外,Knex的文档和其他来源建议参数化绑定作为防止SQL注入的方法。

我很难找到一个可以用JavaScript或使用Knex向我解释的明确示例。

2 个答案:

答案 0 :(得分:8)

我不是Knex.js用户,但是看看文档似乎Knex使用JavaScript对象语法来定义谓词就是它如何实现参数化。

但是,当您使用内置功能时,需要使用whereRaw

查看文档(http://knexjs.org/#Builder-whereRaw)和(http://knexjs.org/#Raw-Bindings)我认为你想这样做:

.whereRaw('question LIKE :term OR note LIKE :term OR user_name LIKE :term', { term: '%' + term + '%' ] } )

Knex没有orWhereRaw,所以如果你想在逻辑上区分谓词,你应该使用简写版本:

term = '%' + term + '%';

.orWhere( knex.raw( 'question  LIKE ?', [ term ] ) )
.orWhere( knex.raw( 'note      LIKE ?', [ term ] ) )
.orWhere( knex.raw( 'user_name LIKE ?', [ term ] ) )

注意?用于位置参数,:term用于命名参数。

答案 1 :(得分:2)

似乎您真正需要担心sql注入的唯一时间是使用knex.raw()或任何其他纯sql命令。换句话说,Knex会自动为您输入输入。

至于标签问题,在搞乱PG指挥官之后,我发现我可以搜索#' s就好了。我只需要在将它们发送到我的后端之前对urta进行编码...有点尴尬,但我今天学到了一些东西。