【问题标题】: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);

【问题讨论】:

    标签: node.js orm query-builder objection.js


    【解决方案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)
    

    【讨论】:

    • 感谢您的回答,但我无法控制查询的创建。我只能在创建查询后修改它。所以我不能使用你的解决方案。
    猜你喜欢
    • 2017-01-01
    • 1970-01-01
    • 2013-03-19
    • 2017-01-02
    • 1970-01-01
    • 2012-12-28
    • 2020-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多