Javascript 如何编写参数化sql查询以防止sql注入?
我最初发现这是一个问题,当时我试图搜索带有hashtag的术语,结果发现它是SQL中的注释分隔符。搜索没有返回任何结果,因为它忽略了hashtag后面的#术语 所以现在我很难找到正确的方法来逃避用户的输入。在我看来,这既可以解决hashtag问题,也可以解决更大的问题,即SQL注入 以下是我正在处理的代码片段:Javascript 如何编写参数化sql查询以防止sql注入?,javascript,sql,postgresql,knex.js,Javascript,Sql,Postgresql,Knex.js,我最初发现这是一个问题,当时我试图搜索带有hashtag的术语,结果发现它是SQL中的注释分隔符。搜索没有返回任何结果,因为它忽略了hashtag后面的#术语 所以现在我很难找到正确的方法来逃避用户的输入。在我看来,这既可以解决hashtag问题,也可以解决更大的问题,即SQL注入 以下是我正在处理的代码片段: function (term) { term = term.toLowerCase() return db('ticket') .select('*') .whe
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}%`)
}
我确实找到了一篇似乎很接近的文章,还有一些其他的东西。此外,Knex的文档和其他来源建议使用参数化绑定作为防止SQL注入的方法
我只是很难找到一个可以用JavaScript或Knex向我解释的清晰示例 我不是Knex.js用户,但从文档来看,Knex使用JavaScript对象语法定义谓词似乎是实现参数化的方式 但是,在使用内置函数时,需要使用
whereRaw
查看文档()和()我认为您希望这样做:
.whereRaw('question LIKE :term OR note LIKE :term OR user_name LIKE :term', { term: '%' + term + '%' ] } )
Knex没有或whereraw
,因此,如果要在逻辑上分隔谓词,则应使用手写版本:
term = '%' + term + '%';
.orWhere( knex.raw( 'question LIKE ?', [ term ] ) )
.orWhere( knex.raw( 'note LIKE ?', [ term ] ) )
.orWhere( knex.raw( 'user_name LIKE ?', [ term ] ) )
注意
?
用于位置参数,而:term
用于命名参数。似乎您真正需要担心sql注入的唯一时间是使用knex.raw()或任何其他纯sql命令。换句话说,Knex会自动为您转义输入
至于标签问题,在与PG指挥官闲逛之后,我发现我可以搜索#的标签。我只需要在将哈希标记发送到后端之前对其进行url编码。。。有点尴尬,但我今天学到了一些新东西。您的数据库排序规则是否特别区分大小写?您不需要将
LOWER
与LIKE
操作符一起使用-这也意味着您的查询将运行得非常慢,因为它无法使用index.IMO。“SQL注入”类似于“2000年问题”:有很多噪音,但并不严重。有两个简单的规则可以避免任何“SQL注入”:1)在前端/中间端使用参数化查询,2)在DB对象上设置适当的DB级别安全性。感谢您的响应@戴:我试过你的建议,但它似乎是区分大小写的。我是db land的新手,您能推荐一些资源来学习使用您提到的索引和排序规则吗?以前从未听说过这些术语。@Abelisto我对此并不十分担心,因为该应用程序是一个内部工具,但它似乎是一个很好的保护措施。你是在建议我在将用户输入发送到后端之前对其进行上游清理?谢谢谢谢你的回复。是的,你提出的两个选择都很好。即便如此,我还是觉得我错过了他们与我已经在做的事情根本不同的地方。我的orWhere中有一个用%装饰的模板字符串。在第一个示例中将术语设置为对象或在第二个示例中将其设置为数组是否实现了参数化绑定?编辑:还应该注意,我仍然无法从数据库中检索hashtag,尽管我可以插入它们。