Skip to content

查询过滤器遇到"不认识的条件"时,应统一报错而不是悄悄放行(所有数据驱动) #2873

Description

@baozhoutao

一句话

现在只有 SQL 驱动会在遇到看不懂的筛选条件时报错(#2704 / #2872 刚修的)。其它数据驱动(MongoDB、内存等)遇到同样的情况仍可能"看不懂就当没这个条件",这有安全隐患。应该让所有驱动行为一致:看不懂就明确报错。

用大白话解释问题

系统在做"列表查询"时,会带上一串筛选条件,比如"只看分配给我的任务""只看没有归属人的记录"。这些条件里有很多"运算符"——等于、不等于、包含、为空、不为空……

问题在于:如果某个运算符拼写变了或系统没见过(比如客户端发来的是 is_null,而驱动只认 equals),驱动有两种可能的反应:

  • 好的反应:直接报错,"我不认识这个条件"。
  • 危险的反应:悄悄把这个条件当作不存在,照常返回数据。

危险就危险在:很多筛选条件其实是权限护栏(比如"只能看自己部门的数据")。如果这条护栏被悄悄忽略,查询就会把本不该看到的数据全都返回出去——用户完全无感,系统也不报警。这正是 #2704 里 SQL 驱动出过的事。

现状

  • SQL 驱动:已在 fix(driver-sql): fail-loud on unknown filter operators; real IS NULL / IS NOT NULL; $not (#2704) #2872 修复——看不懂的运算符会明确报错,不再悄悄放行。
  • MongoDB 驱动 / 内存驱动 / 其它驱动:需要逐个核查,是否也存在"看不懂就当没这条件"的行为。
  • ⚠️ 更理想的做法:在更上游的统一入口(查询解析层 parseFilterAST)就把"合法运算符清单"校验一遍,这样所有驱动都自动受益,不用每个驱动各修一遍。但目前查询引擎(objectql)把筛选条件原样丢给驱动、跳过了这道统一校验,所以现在只能在每个驱动里各自兜底。

建议怎么做

  1. 排查每个数据驱动:遇到不认识的运算符时,到底是报错还是悄悄放行?列个清单。
  2. 决定拦截点:是在统一的查询解析层(parseFilterAST)加一道校验(治本,但要改查询引擎让它不再绕过校验),还是继续在每个驱动里各自补(治标,但分散)。倾向于前者——一处校验,处处生效
  3. 统一行为:所有驱动对"不认识的运算符"一律明确报错,并且报错信息里带上"支持哪些运算符"的提示(和 SQL 驱动现在的报错格式对齐)。
  4. 补测试:每个驱动都加一条"遇到瞎编的运算符必须抛错"的回归测试,防止以后又退化成悄悄放行。

为什么值得单独做

#2872 已经堵上了 SQL 这个最要紧的口子,线上风险最大的场景解决了。但"所有驱动统一 fail-loud + 上游统一校验"牵涉到查询引擎的改动、要动多个包、还要决定拦截点,范围比一个 bug 修复大,所以从 #2704 里拆出来单独跟踪。

相关:#2704#2872

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions