我正在编写一个原始SQL查询,以在我的节点后端实现Postgres全文搜索。我查看了official docs,其中说明了这一点:
plainto_tsquery将无格式文本querytext转换为tsquery。文本被解析和标准化,就像to_tsvector一样,然后& (AND)在幸存的单词之间插入布尔运算符。
但我对所有不同的SQL注入技术都不熟悉,无法确定以下内容是否会被正确转义:
'SELECT * FROM "Products" WHERE "catalog_ts_vector" @@ plainto_tsquery(\'english\', ' + search_term + ')'
用户可以通过URI输入他们想要的任何search_term
。
我是否需要进一步转义/操作,或者此功能是否完全融入plainto_tsquery()
和其他Postgres保护措施?
修改
作为旁注,我打算用.replace(/[^\w-_ .\&]|\(\)/g, ' ')
删除大多数非字母数字字符(包括括号);这应该有很长的路要走,但如果有必要,我仍然很好奇。
答案 0 :(得分:10)
您很可能将pg
模块用作node.js
的PostgreSQL客户端。在这种情况下,您不必担心SQL注入,pg
会阻止它。只是不使用字符串连接来创建查询,使用参数化查询(或prepared statement):
var sql = 'SELECT * FROM "Products" WHERE "catalog_ts_vector" @@ plainto_tsquery(\'english\', $1)';
var params = [search_term];
client.query(sql, params, function(err, result) {
// handle error and result here
});
另请参阅pg
wiki和PostgreSQL Prepared Statment语句的PREPARE部分。
UPD sequelize
怎么样 - 它默认使用pg
模块,但您可以在dialectModulePath
config参数中指定您更喜欢的pg客户端(请参阅{{ 3}})。您也可以在sequelize
中使用参数化查询。更好 - 您可以使用命名参数。所以你的代码将是:
var sql = 'SELECT * FROM "Products" WHERE "catalog_ts_vector" @@ plainto_tsquery(\'english\', :search_term)';
var params = { search_term: search_term }
sequelize.query(sql, Product, null, params).then(function(products) {
// handle your products here
})
Product
是您的续集产品型号。