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

How to properly escape raw SQL query (plainto_tsquery) in Postgres / node

我正在编写原始 SQL 查询以在我的节点后端中实现 Postgres 全文搜索。我查看了 official docs,其中状态:

plainto_tsquery transforms unformatted text querytext to tsquery. The text is parsed and normalized much as for to_tsvector, then the & (AND) Boolean operator is inserted between surviving words.

但我对所有不同的 SQL 注入技术还不够熟悉,无法确定以下内容是否会被正确转义:

'SELECT * FROM "Products" WHERE "catalog_ts_vector" @@ plainto_tsquery(\'english\', ' + search_term + ')'

用户将能够通过 URI 输入任何内容 search_term

我是否需要做进一步的工作 escaping/manipulation,或者此功能是否已完全纳入 plainto_tsquery() 和其他 Postgres 安全措施?

编辑

作为旁注,我计划用 .replace(/[^\w-_ .\&]|\(\)/g, ' ') 删除大多数非字母数字字符(包括括号);这应该有很长的路要走,但我仍然很好奇这是否有必要。

您很可能正在使用 pg module as PostgreSQL client for node.js. In this case you don't need to worry about sql injection, pg prevents it for you. Just not use string concatination to create query, use parameterized queries (or prepared statement):

var sql = 'SELECT * FROM "Products" WHERE "catalog_ts_vector" @@ plainto_tsquery(\'english\', )';
var params = [search_term];

client.query(sql, params, function(err, result) {
    // handle error and result here
});

另请参阅 Prepared Statment part of pg wiki and PostgreSQL PREPARE 声明。

UPD 那么 sequelize - 它默认使用 pg 模块,但您可以在 dialectModulePath 配置中指定您更喜欢的 pg 客户端参数(参见 here)。您也可以在 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 是您的续集产品型号。