Skip to content

phoneOtp.cooldownSeconds 配成大于 1 小时会被静默截断 —— OtpSendGuard 的历史 TTL 硬编码 1 小时 #4808

Description

@os-zhuang

#4790 的 dev 在实施中发现并记录,PM 代为立单(dev 判断"属默认值不会触及的边角"而只写进报告,我认为它够得上一条 issue —— 理由见下)。未认领。改动前后行为一致,非 #4806 引入。

现象

OtpSendGuard 的发送历史 TTL 硬编码为 1 小时。若把 phoneOtp.cooldownSeconds 配成大于 3600,冷却判定所依赖的历史记录会先被滚动窗剪枝掉,于是:

  • 声明:「两次发送之间至少间隔 N 秒」(N > 3600);
  • 实际:超过 1 小时之后历史就没了,冷却最多只有 1 小时;
  • 信号:。配置被接受,没有校验错误,没有 warn。

为什么值得立单,而不只是记在报告里

dev 的判断(边角、默认值不会触及)是对的,但这恰好是本仓正在系统性关掉的那一类,而且是其中最隐蔽的一种:

配置项不是被忽略(那还容易发现),而是被接受、被部分执行。管理员设了 2 小时冷却,系统给了 1 小时,而且看起来一切正常 —— 反滥用强度是声明值的一半,没有任何东西说出来。这与 #4790 本身(预算按节点倍增、无信号)是同一个形状,只是维度从"节点数"换成了"时间"。

按 ADR-0049(declared = enforced):要么真的支持 > 1 小时的冷却,要么在配置校验期拒绝这个值并说明上限。静默截断是唯一不该保留的选项。

修法方向(择一,倾向 1)

  1. 让 TTL 跟随配置:历史保留时长取 max(1h, cooldownSeconds),冷却按声明值真正生效。最符合"声明即强制",代价是超长冷却会让历史条目留得更久(可加一个合理上限,但那个上限要显式拒绝超出的配置,而不是截断)。
  2. 在配置校验期拒绝 cooldownSeconds > 3600,错误信息说明当前实现上限及原因。诚实、成本最低,但把一个能力限制写死进契约,以后想放开要走变更。

不建议第 3 条(维持现状 + 文档说明)—— 文档拦不住配置文件里那个数字。

验收

  • cooldownSeconds 大于 1 小时时,要么真的生效,要么被明确拒绝;两种都可接受,静默截断不可接受;
  • 默认配置行为不变(有测试证明,别为边角改动误伤主路径);
  • 若取方案 1,加一条测试:冷却设为 > 1 小时时,超过 1 小时后的发送仍被拒。

关联

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions