Skip to content

plugin-auth: convertWhere()not_in / starts_with / ends_with 没有分支,谓词被整条丢弃 —— 认证路径上的过滤放大 #5813

Description

@baozhoutao

实测于 origin/main@1624f4a,在实施 #5710(同一个函数的 contains 支)时发现。#5710 不同类:#5710 是「译错了」($regex 把字面值当模式),本单是「根本没译」—— 谓词消失,过滤放大

测到的东西

packages/plugins/plugin-auth/src/objectql-adapter.tsconvertWhere() 是一串 if / else if,只覆盖 eq / ne / in / gt / gte / lt / lte / contains

better-auth 的算子词表(@better-auth/core/src/db/adapter/index.ts:308-320)是:

eq, ne, lt, lte, gt, gte, in, not_in, contains, starts_with, ends_with

对不上的三个 —— not_instarts_withends_with —— 落在链尾之外,filter不写任何键。没有 else 兜底,没有告警。一个只带这类条件的 where 因此编成 {}:

  • findMany / count 变成全表(受 limit 截断);
  • update / delete / consumeOne 走的是「先 findOne(filter) 再按 id 写」,{}findOne 返回任意一行(通常是第一行),于是写到了错误的记录上。

活体调用方

GET /api/v1/auth/admin/list-users(已挂载,auth-route-ledger.ts:161)直接把查询参数推进 where(better-auth dist/plugins/admin/routes.mjs:358-368):

  • searchOperator 的枚举是 contains | starts_with | ends_with —— 后两个命中本缺陷;
  • filterOperator 的枚举就是整张 whereOperators —— 含 not_in

所以 ?searchValue=abc&searchOperator=starts_with 今天返回的是「全部用户」而不是「以 abc 开头的用户」,?filterField=email&filterOperator=not_in&filterValue=... 同理不排除任何人。管理台的用户检索是它的主要消费者。

为什么这是缺陷而不是「未实现的可选能力」

丢一个谓词不是把结果变窄,是变宽;在读路径上等于放大可见集合(#3948 反复论证过的形状,driver-memory 的匹配器 default: 臂和 objectql 的 having 都为此改成了拒收)。这里的放大还发生在身份表上。

修法(建议)

三个算子在 FILTER_OPERATORS 里都有现成对应,一一直译即可:

better-auth ObjectQL
not_in $nin
starts_with $startsWith
ends_with $endsWith

同时把链尾的静默补上:未识别的算子应当响亮拒收(抛错),而不是写不出键就算了 —— 否则 better-auth 下次加算子时,这个洞会以同样的方式重开一次。

相关

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions