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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions