如何在Postgres / node中正确转义原始SQL查询(plainto_tsquery)

时间:2015-04-03 17:04:38

标签: node.js postgresql security sql-injection

我正在编写一个原始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, ' ')删除大多数非字母数字字符(包括括号);这应该有很长的路要走,但如果有必要,我仍然很好奇。

1 个答案:

答案 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是您的续集产品型号。