Skip to content

分享侧:GA 翻转后越界的 sharing condition 在 enforceability 门下根本不报(让渡给 validateStackExpressions,而它按语法说话) #6833

Closed as not planned

Description

@os-project-manager

观察类 finding,来自 #6778 / PR #6831 的实施(该 PR 有意把这一侧排除在外,理由见下)。未认领,不构成派单请求。

事实(origin/main c32944d67 实测)

packages/lint/src/validate-sharing-rule-enforceability.ts:197:

const result = compileCelToFilter(input, { variables: {} });
if (result.ok) return;
// 语法归 validateStackExpressions
if (result.reason === 'parse-error') return;

下推编译器有意把 DEFAULT_LIMITS 越界折叠进 reason: 'parse-error'(cel-to-filter.ts:133-138 写明理由:这是每个消费者都已经路由到拒绝路径的 reason)。于是 v17 GA 翻转(CEL_PUSHDOWN_LIMITS_MODE 由 rc-grace 改为 fail-closed)之后,一条语法完美但超出平台解析预算的 sharingRules[].condition:

  • 在 validateSharingRuleEnforceability 里走到上面这行 return,一条都不报;
  • 规则本身在 boot 时会被 bootstrapDeclaredSharingRules 跳过(不写 sys_sharing_rule,不产生任何 sys_record_share 授权),只留一行 boot WARN。

即:声明了一条分享规则,它什么也不授予,而 enforceability 门对此沉默。

与 #6778 的区别(为什么 PR #6831 没有顺手一起改)

#6778 的缺陷形状是贴错标签:RLS 侧确实报了,但报在 rls-predicate-unparseable 名下,提示语讲 SQL 与 CEL 的方言混淆。分享侧的形状是让渡:它不报错 id,而是有意不报,把语法交给 validateStackExpressions。二者不是同一个缺陷在两个入口,因此 #6778 的「同样的输入照样被拒,只是说对话」这一无行为变更口径,不能原样套到这里。

要修就得先回答:越界是否应当停止让渡给 validateStackExpressions?那会改变「哪条规则报某个输入」,且 validateStackExpressions 覆盖全栈每一条 CEL 表达式,不止 sharingRules——是一个比 #6778 大一档的面。

未验证的相邻问题(留给分诊,本 finding 未测)

validateStackExpressions 在越界时具体说什么、是否也按语法口径措辞,本次没有测量。若它同样按语法说话,那这条 finding 的实际用户影响会比「只是沉默」更大一些。

为什么是观察类而非缺陷

翻转尚未发生(cel-pushdown-limits.ts:75 当前为 'rc-grace'),宽限窗口内越界 condition 仍被放行并编译,所以今天没有用户会撞上。严重度按 #4949 的口径交由分诊轮评级,不在此自行判定。

Refs: #6778、PR #6831(RLS 侧的对应修复)、#6132 / PR #6766(GA 开关的来源)

Activity

  1. os-project-manager commented on Aug 9, 2026

    @os-project-manager
    CollaboratorAuthor

    Triage (maintainer-authorized one-off pass, 2026-08-09, registered on #6015): promoted finding → pm:queue (domain:spec-tooling kept). After the GA flip a syntactically-perfect but over-budget sharing condition produces a rule that grants nothing, with the enforceability gate silent about it — a declared security surface that silently no-ops is exactly what that gate exists to catch. Deliverable: make the limits-exceeded case distinguishable from parse-error at the gate (either the pushdown compiler stops folding it into parse-error, or the gate re-probes limits explicitly) so the author is told at lint time, not by a boot WARN.


    Generated by Claude Code

  2. os-project-manager commented on Aug 9, 2026

    @os-project-manager
    CollaboratorAuthor

    认领 · domain:spec-tooling 座位派单 — 会话 session_01AZgRyPVwi1jLb1mNNuUQ9o(座位贴 #6018),分支 claude/issue-6833-sharing-over-budget-visible,pm:queue → pm:dispatched。

    三查(本轮实测):① ㉔ 落点 packages/lint/src/validate-sharing-rule-enforceability.ts 最新提交 bf1edeffd(#4983 via PR #5008)——自立单以来零改动;姊妹先例 #6778/PR #6831(ca522e9ff)已在 RLS 侧落地,是本单的直接参照;② 竞态:线程仅分诊晋级评论;③ 不相交:同批 #6967、#6751 均不触 packages/lint。

    注意与 #6778 的差异,分诊口径已明确:RLS 侧是「贴错标签」,本单是「根本不报」(让渡给按语法说话的 validateStackExpressions)。分诊给了两条路(编译器停止折叠 / 门禁显式重探界限),这允许行为变更(哪条规则报该输入会变)——与 #6778 的「无行为变更」口径不同,派单按分诊的新口径执行,但要求实测披露变更前后「谁报什么」的完整对照表。


    Generated by Claude Code

  3. os-project-manager commented on Aug 9, 2026

    @os-project-manager
    CollaboratorAuthor

    座位处置(domain:spec-tooling,会话 session_01AZgRyPVwi1jLb1mNNuUQ9o,座位贴 #6018):前提被实测证伪,关单(not planned),零代码。

    那格没人测过的,测了——结果推翻本单

    本单立案时明确记录「未测:validateStackExpressions 在越界时到底说什么」。派单要求先测这格再设计。实测(#6831 的三个越界夹具,经真实的 runAuthoringRules('validate', …) 门,两个 GA 开关位置各跑一遍):

    输入 开关 validateStackExpressions sharing 门 作者净信号
    越界(三种界各一) rc-grace 1 条 gating ERROR,消息带 Exceeded maxAstNodes (256) 0 红,阻断
    越界(同上) fail-closed 同上 0(让渡) 红,阻断
    真语法错 两者 1 条 ERROR 0(让渡) 红,阻断
    合法 两者 0 0 绿

    「一条都不报」不成立:让渡的对象真的在报,且消息已点名界与取值。更强的反转:validateExpression 走 celEngine.compile,无条件应用 DEFAULT_LIMITS、从不读 GA 开关(全文件无一处 celPushdownLimitsMode,座位已逐条复核)——所以今天在宽限窗口内,lint 就已经比运行时更严,方向与本单担心的正好相反。生产者自己也写了(cel-engine.ts:282):verdict 归 validateExpression 所有,「它同时报语法错与越界错」。

    为什么不做分诊给的两条路

    • 门侧镜像(fix(lint): 超预算的 RLS 谓词有了自己的规则 id rls-predicate-over-budget (#6778) #6831 式):会给一条已经红了的行加第二条错误、配第二种处方——正是 sharing 门 docblock 自己拒绝的 double-report。且实测无任何门只跑 sharing 门不跑表达式门(前者 CLI_ONLY,后者 commands: ALL),第二条报告没有服务对象。
    • 编译器路:为一个 build 已经拒绝的类去改 packages/formula 的 reason 契约,爆炸半径无法论证。

    dev 的反向验证也如实报了未命中:它预判 rc-grace 格在表达式门下是绿(单据的断言),实测是红——这个未命中本身就是发现。

    幸存的真缺陷,已另立 #7080(窄卡,未定级)

    不是 sharing 特有、也不是沉默:是 validateExpression 把方言处方 trailer(「predicates are bare CEL…」)逐字节复用到越界类错误上——对语法完美、只是太大的 CEL,教作者去改方言,改了必然回退。落点 packages/formula/src/validate.ts,一处修好覆盖全部 ~10 个表达式槽位;是 #6778/#6831 在解释器侧门的真正对应物。cel-pushdown-limits.ts docblock 的「Nothing else needs to move at GA」完备性缺口(第三个门 mode-agnostic,属良性且 GA 时自愈)一并折入该卡,建议只修 docblock 文字。

    关单理由:premise falsified;卡的价值已兑现为上面这张测量表与 #7080。


    Generated by Claude Code

  4. os-project-manager commented on Aug 9, 2026

    @os-project-manager
    CollaboratorAuthor

    更正:上一条评论里的「#7080」是错的——那条评论发出时窄卡尚未创建,编号是我预写的,不该那么做。真实单号是 #7073。其余内容不变。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

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