fix: 安全与运行时正确性修复(H1/H2 + M2/M4/M5/L4/L5)#10
Open
lgy1027 wants to merge 3 commits into
Open
Conversation
H1: LLMGateway init 时缓存校验过的 IP,请求时 pin 到缓存 IP 而非每次重新解析;新增 _assert_no_dns_rebind 在请求前再校验 一次当前 DNS 与缓存一致,不一致拒绝调用并降级到 extractive, 防 init→request 之间 DNS rebinding 重定向到公网。 allow_public 模式跟随 DNS 轮询,不缓存不校验。 H2: 删除 realtime_auth.py WS loopback 集合里的 'testclient' (Starlette TestClient 固定 host,属为测试开后门);在 is_trusted_browser_origin 补注释说明无 Origin 放行是有意为之 (浏览器同源 fetch 部分实现不携带 Origin),CSRF 由不可信 Origin 拒绝防护,本机隔离走 DEPLOYMENT_MODE=lan / LOCAL_AUTH_DISABLED=false。 补充 6 个回归测试:DNS rebind 拒绝、allow_public 不校验、 可信 Origin 放行、无 Origin 放行、testclient 不再放行 WS。
M2: InferenceCoordinator 给 offline 加饿死超时(30s),超时后放宽 进入条件为 not active 并置 _offline_starving 让 live 谦让一次,保证 连续会议接力(live_waiters 恒>0)不饿死 refinement job。用单层 wait_for 超时避免 wait_for 嵌套的锁陷阱。 M4: audio_processor 超时分支(队列暂空)不再重置 ctx.last_full_text。 超时只是队列暂空非语音段结束,重置基准会让下一段含旧前缀的 ASR 文本 被当增量重发 → 前端重复字。静音触发的 reset 语义不变。 M5: ASR _load_with_fallback 超时放弃设备后置 cancelled flag,daemon worker 在阶段边界(snapshot_download / from_pretrained 之间)主动 return,减少与下一设备加载线程并发占显存/内存。 L4: 三引擎 compare_and_identify 在 embedding=None 时返回 'Spk_unknown' 而非 'Unknown',符合 ^Spk_ 格式,与下游默认值及 speaker_id 校验一致。 L5: realtime_auth 加进程级 WS 连接速率限制(per-IP 20/60s,超限 close 4401),补 HTTP 限流覆盖不到的 WS 路径,防空打 WS 占 fd/协程。 conftest 加 autouse fixture 清理限流计数器防跨测试污染。 补充测试:offline 饿死调度、超时不重置 last_full_text、三引擎 Spk_unknown 格式、WS 限流阈值/per-IP 独立。
…cheduling-and-stream-correctness # Conflicts: # app/services/realtime_auth.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概述
合并两条修复分支,覆盖代码审核发现的安全(High)与运行时正确性(Medium/Low)问题。
安全修复(High)
H1 — LLM DNS pinning TOCTOU(
app/services/llm_gateway.py)__init__缓存校验过的 IP,请求时 pin 到缓存 IP 而非每次重新解析;新增_assert_no_dns_rebind在请求前再校验一次当前 DNS 与缓存一致,不一致拒绝调用并降级到 extractive。防 init→request 之间 DNS rebinding 重定向到公网。allow_public模式跟随 DNS 轮询,不缓存不校验。H2 — WS
testclient后门 + 威胁模型文档化(realtime_auth.py/security.py)删除 WS loopback 集合里的
testclient(Starlette TestClient 固定 host,为测试开后门)。is_trusted_browser_origin注释说明无 Origin 放行是有意为之(浏览器同源 fetch 在部分实现如 Firefox 下不携带 Origin,强制要求会打断 SPA);CSRF 由不可信 Origin 拒绝防护;本机隔离走DEPLOYMENT_MODE=lan/LOCAL_AUTH_DISABLED=false。运行时正确性(Medium/Low)
M2 — InferenceCoordinator 不饿死 offline(
app/runtime.py)offline 加饿死超时(30s),超时后放宽进入条件为
not active+ 置_offline_starving让 live 谦让一次。连续会议接力(live_waiters 恒 >0)不再无限期饿死 refinement job。用单层wait_for超时避开嵌套锁陷阱。M4 — 超时不重置
last_full_text(app/api/websocket.py)超时只是"队列暂空"非"语音段结束",重置基准会让下一段含旧前缀的 ASR 文本被当增量重发 → 前端重复字。静音触发的 reset 语义不变。
M5 — ASR 加载超时清理 daemon 线程(
engine/asr_engine.py)超时放弃设备后置
cancelledflag,daemon worker 在snapshot_download/from_pretrained阶段边界主动 return,减少与下一设备加载线程并发占显存/内存。L4 — 声纹 ID 格式统一(三引擎)
compare_and_identify在embedding=None时返回Spk_unknown而非Unknown,符合^Spk_格式,与下游默认值及 speaker_id 校验对齐。L5 — WebSocket 连接速率限制(
app/services/realtime_auth.py)进程级 per-IP 滑动窗口(20/60s,超限
close 4401),补 HTTP 限流覆盖不到的 WS 路径,防空打 WS 占 fd/协程。conftest 加 autouse fixture 清理计数器防跨测试污染。测试
说明
DEPLOYMENT_MODE=lan/LOCAL_AUTH_DISABLED=false。