【问题标题】:Knex not properly escaping raw postgres queriesKnex 未正确转义原始 postgres 查询
【发布时间】:2020-11-20 00:23:58
【问题描述】:

我正在使用 Knex(带有 typescript)来尝试查询 postgres 数据库。我的数据库表products 有一个列name,当用户在搜索框中键入时,我想搜索该列。例如,仅包含字母“p”的查询应返回名称中包含以“p”开头的单词的所有产品。为此,我使用了ts_vectorts_query 函数。我的查询如下所示:

const query = ... // got from user input
const result = await knex(knex.raw('products'))
  .whereRaw(`to_tsvector(name) @@ to_tsquery('?:*')`, query)
  .select('*')

当我运行此查询时,我收到以下错误:

Unhandled error { error: select * from products where to_tsvector(name) @@ to_tsquery('$1:*') - bind message supplies 1 parameters, but prepared statement "" requires 0

如果我将whereRaw 行替换为:.whereRaw(`to_tsvector(name) @@ to_tsquery('p:*')`),它会正确运行查询,选择名称中包含以 P 开头的单词的产品。

似乎 postgres 语法和 knex 的原始查询存在一些冲突。我想使用原始查询而不是 `${query}:*`,因为我希望我的输入被清理并防止 SQL 注入。我怎样才能让 Knex 正确地避免这种情况?

我尝试了各种引号、斜杠和冒号的组合,但似乎都不起作用。任何帮助将不胜感激。

【问题讨论】:

    标签: sql postgresql escaping full-text-search knex.js


    【解决方案1】:

    PostgreSQL 不处理引号内的占位符(我有点惊讶 knex 这样做)。

    您需要在 PostgreSQL 中明确地进行连接:

    .whereRaw(`to_tsvector(name) @@ to_tsquery(? ||':*')`,query)
    

    或在打字稿内:

    .whereRaw(`to_tsvector(name) @@ to_tsquery(?)`, query+":*")
    

    【讨论】:

    • Knex 对插入的 SQL 一无所知(它没有 SQL 解析器),因此 knex 无法知道引号内是否有内容(即使只是以稳健的方式解析引号也是并不像人们想象的那么微不足道)。
    猜你喜欢
    • 1970-01-01
    • 2020-01-30
    • 1970-01-01
    • 2021-02-20
    • 2021-02-11
    • 1970-01-01
    • 1970-01-01
    • 2017-09-30
    • 2020-07-13
    相关资源
    最近更新 更多