Objection.js:所有 where 子句添加后是不是可以用括号括起来?

Posted

技术标签:

【中文标题】Objection.js:所有 where 子句添加后是不是可以用括号括起来?【英文标题】:Objection.js: Can all where clauses be enclosed in parentheses after they have been added?Objection.js:所有 where 子句添加后是否可以用括号括起来? 【发布时间】:2020-09-30 13:47:43 【问题描述】: 代码示例
// Creates an Objection query. 
// I have no control over the creation of the query. I can only modify the query after it has been created.
// Example: "select `todos`.* from `todos` where `text` = ?"
const objectionQuery = thirdPartyService.createQuery(userControlledInput);
// Adds an access check. Example "select `todos`.* from `todos` where `text` = ? and `userId` = ?"
objectionQuery.andWhere("userId", currentUser.id);

上面的例子有一个安全漏洞。如果thirdPartyService 生成这样的查询:

select `todos`.* from `todos` where `text` = ? or `id` = ?

那么在添加访问检查后我们会得到如下查询:

select `todos`.* from `todos` where `text` = ? or `id` = ? and `userId` = ?

而且这个查询可以返回不属于当前用户的数据。 要修复此错误,我们需要将用户控制的条件括在括号中:

select `todos`.* from `todos` where (`text` = ? or `id` = ?) and `userId` = ?

但是我如何使用异议查询生成器来做到这一点?我想像这样:

const objectionQuery = thirdPartyService.createQuery(userControlledInput);
wrapWhereClauses(objectionQuery);
objectionQuery.andWhere("userId", currentUser.id);

【问题讨论】:

【参考方案1】:

一种方法是将原始查询包装为子查询/临时表:

MyModel.query().from(thirdPartyService.createQuery(userControlledInput)).where(...)

(请告诉我这是否有效,我还没有测试过)

【讨论】:

是的,它可以工作并创建如下查询:select * from (select todos.* from todos` where text = ?) where userId = ?`。谢谢。【参考方案2】:

来自docs:您可以通过将函数传递给任何where* 方法来为查询添加括号:

await Todo.query()
  .where('userId', 1)
  .where(builder => 
    builder.where('text', 2).orWhere('id', 3);
  );

会导致

select * from "todos" where "userId" = 1 and ("text" = 2 or "id" = 3)

【讨论】:

感谢您的回答,但我无法控制查询的创建。我只能在创建查询后修改它。所以我不能使用你的解决方案。

以上是关于Objection.js:所有 where 子句添加后是不是可以用括号括起来?的主要内容,如果未能解决你的问题,请参考以下文章

Linq to SQL 多个条件 where 子句

Objection.js 中的多对多关系

始终选择表中所有记录的 WHERE 子句

在 Objection.js 中按急切结果计数排序记录并实现分页?

在删除表格时在 Objection.js 中保留关系图

联合所有 where 日期子句