Skip to content

fix(push): reject revoked WebSocket tokens#84

Draft
ULookup wants to merge 1 commit into
3.0-devfrom
fix/21-reject-revoked-ws
Draft

fix(push): reject revoked WebSocket tokens#84
ULookup wants to merge 1 commit into
3.0-devfrom
fix/21-reject-revoked-ws

Conversation

@ULookup

@ULookup ULookup commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Primary Issue

Closes #21

Target Version

3.0,PR base 为 3.0-dev;merge-base 为 a75fc8721b99e5c0b4421d0c58b5618bbe71ff31

Scope

为 Push WebSocket CLIENT_AUTH 注入 JwtStore,在任何连接表、在线路由、Presence 或补送副作用之前执行一次吊销查询。查询结果区分未吊销、已吊销和依赖不可用;后两者统一使用稳定的 policy_violation / auth failed 关闭语义并分别计数。保留旧 is_revoked bool 接口的兼容行为,移除 JwtStore 错误日志中的 JTI。新增 Go Functional 用例 FN-WS-09、测试客户端关闭观测能力,并同步认证核心流程文档。

同一提交包含构建过程中发现并由 #82 驱动的一行 Push stale-reaper 线程参数交接修复,使本版本线的 Push 目标恢复可编译;Refs #82

Non-goals

不进行每消息或每心跳吊销查询;不主动踢出已经建立的存量连接;不引入本地吊销缓存;不全局改变 Gateway 等旧调用方的 fail-open 策略;不解决 #23/#48 的全栈 Redis 故障治理;不修复 #83 的 Presence 在线观测问题。

Architecture Impact

No — 未改变服务边界、协议、持久化所有权或基础设施拓扑;Push 复用已有 Redis 客户端及连接池,仅在 WebSocket admission 增加一次查询。

Core-flow Impact

Yes — WebSocket 认证顺序变为 JWT 验证 → Redis 吊销状态 → 连接/路由/Presence/补送副作用;依赖不可用时该安全边界 fail-closed。

Updated Skills

.agents/skills/chatnow-orienting/references/core-flows.md

RED Evidence

命令:cd tests && go test -tags=func ./func/... -run '^TestFN_WS_RevokedTokenRejected$' -v -count=1

旧 Push 上用例进入 TestFN_WS_RevokedTokenRejected,在 tests/func/ws_notify_test.go:260context deadline exceeded 失败,消息为 Push must close a revoked WebSocket admission;证明已登出令牌仍能维持 WebSocket 连接。

GREEN Evidence

命令:cd tests && go test -tags=func ./func/... -run '^TestFN_WS_RevokedTokenRejected$' -v -count=1

在隔离的本地完整栈和临时独立 Redis 测试端点上新 Push 返回 PASS,目标用例耗时 1.94s,包结果为 ok chatnow-tests/func 44.535s。用例同时验证:已吊销连接被关闭、被拒绝用户保持 OFFLINE、有效令牌控制连接至少保持 1 秒。

Regression Verification

  • cmake --build build --target push_server -j2:通过,[100%] Built target push_server
  • cd tests && go test ./...:通过,默认 Go 测试与全部无 tag 包均成功。
  • cd tests && go test ./pkg/...:通过,包含 pkg/clientpkg/contracts
  • git diff --check origin/3.0-dev...HEAD:通过,无格式错误。
  • cd tests && go test -tags=func ./func/... -run '^TestFN_WS_(RevokedTokenRejected|Reconnect)$' -v -count=1:未全通过;FN-WS-09 通过,既有 FN-WS-06 在 Presence ONLINE 观测处 10 秒超时,已建 Make WebSocket online observation deterministic #83

Security and Compatibility

Security: 关闭 Push admission 的吊销绕过;Redis 查询异常和空 JTI 均拒绝,日志与关闭原因不包含 token/JTI;已吊销与依赖不可用分别提供 bvar 计数。
Compatibility: 不改变 Protobuf、HTTP/WebSocket 帧格式或旧 JwtStore::is_revoked bool 语义;有效令牌路径保持可连接。新增的同步 Redis GET 只发生在 admission,不进入消息/心跳热路径。
Migration: 无 schema、配置或数据迁移;部署新 Push 实例即可生效,滚动期间旧实例仍保留原漏洞,完成滚动后边界一致。

Unverified Items

Rollback Plan

触发条件:有效令牌 admission 出现持续误拒绝、Redis 延迟导致连接建立 SLO 明显退化,或 Push 启停线程出现回归。由获授权维护者回滚提交 bbf4bb42b2cd85c07edcb3bf736a83298fa7b62c 并滚动部署上一 Push 二进制;无数据迁移或持久化回滚。回滚会重新暴露 #21 的安全缺陷,因此必须由人工批准,并优先通过前滚修复恢复 fail-closed。

Stacked PR Dependencies

Dependency: None;#82 是同一提交内的独立 companion Issue,不形成 PR ancestry 依赖。
Final target version: 3.0-dev
Merge order: None
After predecessor merge: None

Full-diff Self-review

Base and range: origin/3.0-dev...bbf4bb42b2cd85c07edcb3bf736a83298fa7b62c,merge-base a75fc8721b99e5c0b4421d0c58b5618bbe71ff31
Verdict: 完整差异为 6 个文件、122 insertions/21 deletions;认证顺序、一次查询上限、fail-closed、指标、无 JTI 日志、旧接口兼容、Go Functional 分层和核心流程同步均符合 Issue。无 Protobuf/生成物/迁移/凭据变更;用户原有未跟踪文件未暂存、未提交。已披露 #82 的构建修复与 #83 的范围外失败,未发现其他无关改动。

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant