Skip to content

fix(security): 代码审查安全加固 — Gateway/沙箱/TLS/存储/Offload 缺陷修复#391

Open
rainforest888 wants to merge 1 commit into
TencentCloud:mainfrom
rainforest888:fix/security-hardening
Open

fix(security): 代码审查安全加固 — Gateway/沙箱/TLS/存储/Offload 缺陷修复#391
rainforest888 wants to merge 1 commit into
TencentCloud:mainfrom
rainforest888:fix/security-hardening

Conversation

@rainforest888

Copy link
Copy Markdown

背景

src/index.ts 做了一轮安全 + 健壮性代码审查,修复发现的缺陷。本 PR 仅含审查修复,不改变公开 API 行为。

验证

  • vitest run67/67 通过
  • tsc(strict,含 src + index.ts)→ 零新增错误(baseline 38 行历史错误 = 修复后 38 行;本 PR 引入的唯一一处已在提交前修正)

修复清单

HIGH

位置 问题 修复
src/gateway/server.ts parseJsonBody 无 body 大小限制,且默认免鉴权 → 远程 OOM DoS 加 16 MiB 上限,超限返回 413 并断开连接
src/adapters/standalone/llm-runner.ts resolveSandboxedPathstartsWith 无尾部分隔符 → ../tdai-backup 类前缀穿越 改为 resolved === root || resolved.startsWith(root + path.sep)
src/offload/backend-client.ts 所有后端 HTTPS 调用无条件 rejectUnauthorized:false → MITM 窃取 API key 默认校验;仅 TDAI_BACKEND_INSECURE_TLS=1 时 opt-in
src/core/store/tcvdb.ts session_key/session_id 直接插值进过滤表达式 → 注入跨会话泄露 新增 escapeTcvdbFilterString,转义 \"

MED

  • gateway/server.ts/seed 禁止覆盖 llm.* 防端点劫持;500 回 generic "Internal error" 防内部信息泄露;stop()closeAllConnections() 防关闭挂起;safeEqual 改 SHA-256 后比较防时序泄漏 key 长度;seed outputDir 加随机后缀防同秒并发碰撞
  • offload/opik-tracer.tscreateRequire(import.meta.url) 加载 opik(ESM 下 require 失效导致 tracing 永久关闭);trace 内容统一截断到 2000 字符防未脱敏 tool 输出外泄
  • offload/storage.ts:新增 per-file 锁串行化 appendOffloadEntries/markOffloadStatus,防并发 fire-and-forget 调用 clobber 与去重失效;writeStateFile/rewriteOffloadEntries 改原子 tmp+rename
  • offload/state-manager.tsnextMmdNumber 加 per-instance 锁防同号 MMD 文件碰撞;抽出 rebuildOffloadState 供非标准 sessionKey 路径重建 offload ID 集
  • index.tsgateway_stop 始终 await cleanup 再 resetStores,防热重载 SQLITE_BUSY;sharedMemoryCleaner 检测 retentionDays/cleanTime 变更并重建
  • core/profile/profile-sync.ts:scene_blocks 改 backup-swap,rename 失败时保留原件(原实现先删后 rename,失败则丢失)
  • core/hooks/auto-recall.ts + core/store/embedding.ts:recall 超时 abort 贯穿到 embedding HTTP(AbortSignal.any 合并超时与外部信号),搜索后短路

LOW

  • core/store/sqlite.ts:6 处 Buffer.from(emb.buffer)byteOffset/byteLength(防 subarray 视图写整 buffer);加载 sqlite-vec 后 enableLoadExtension(false)
  • core/store/tcvdb-client.ts + tcvdb.ts:新增 TcvdbClient.close() 释放 undici 连接池,store close() 调用之
  • offload/fast-token-estimate.ts:astral 字符(emoji / CJK ext B)跳过低代理,修正约 2× token 高估
  • offload/local-llm/index.ts:L1.5 解析失败 fallback 改 all-null,真正触发 normalizeJudgment 的 "LLM 不可用" 重试路径
  • core/report/reporter.tsgetOrCreateInstanceId 加 in-flight 锁 + 原子写,防并发冷启动重复 ID 与半写损坏
  • offload/session-registry.ts:LRU 驱逐跳过有 pending 的会话并先 save(),防缓冲工具对丢失

改动范围

17 个文件,+490 / -188。均为审查驱动的小幅修补,无新增依赖。

备注

部分修复(如 enableLoadExtension 重置、Buffer.from 视图)当前为防御性加固(现有调用路径下暂不触发),按纵深防御原则一并修复。

对 src/ + index.ts 做了一轮安全 + 健壮性审查并修复发现的问题。
全部为工作区改动,未改公开 API 行为;vitest 67/67 通过,tsc 零新增错误
(baseline 38 行历史错误 = 修复后 38 行)。

HIGH
- gateway/server.ts: parseJsonBody 加 16MiB body 上限 + 413,防 OOM 远程 DoS
- adapters/standalone/llm-runner.ts: resolveSandboxedPath 加尾部分隔符,
  堵住 ../tdai-backup 类前缀穿越
- offload/backend-client.ts: 移除无条件 rejectUnauthorized:false,改为
  TDAI_BACKEND_INSECURE_TLS=1 显式 opt-in,默认校验
- core/store/tcvdb.ts: 新增 escapeTcvdbFilterString,转义 session_key/
  session_id 过滤表达式插值,防跨会话数据泄露

MED
- gateway/server.ts: /seed 禁止覆盖 llm.* 防端点劫持;500 回 generic 信息
  防泄露;stop() 用 closeAllConnections 防挂起;safeEqual 改 SHA-256 比较
  防时序泄漏;seed outputDir 加随机后缀防并发碰撞
- offload/opik-tracer.ts: createRequire 加载 opik(ESM 下 require 失效);
  trace 内容统一截断到 2000 字符防脱敏
- offload/storage.ts: per-file 锁串行化 appendOffloadEntries/markOffloadStatus
  防并发 clobber 与去重失效;writeStateFile/rewriteOffloadEntries 改原子写
- offload/state-manager.ts: nextMmdNumber 加锁防同号碰撞;抽出
  rebuildOffloadState 供非标准 sessionKey 路径重建 offload ID 集
- index.ts: gateway_stop 始终 await cleanup 再 resetStores,防热重载
  SQLITE_BUSY;sharedMemoryCleaner 检测配置变更并重建
- core/profile/profile-sync.ts: scene_blocks 改 backup-swap,rename 失败
  时保留原件
- core/hooks/auto-recall.ts + core/store/embedding.ts: 超时 abort 贯穿到
  embedding HTTP(AbortSignal.any 合并),搜索后短路

LOW
- core/store/sqlite.ts: 6 处 Buffer.from 补 byteOffset/byteLength;
  加载 sqlite-vec 后 enableLoadExtension(false)
- core/store/tcvdb-client.ts + tcvdb.ts: 新增 close() 释放 undici 连接池
- offload/fast-token-estimate.ts: astral 字符跳过低代理,修正约 2x 高估
- offload/local-llm/index.ts: L1.5 解析失败 fallback 改 all-null,真正
  触发 LLM 不可用重试路径
- core/report/reporter.ts: getOrCreateInstanceId 加 in-flight 锁 + 原子写
- offload/session-registry.ts: LRU 驱逐跳过有 pending 的会话并先 save()
@Maxwell-Code07

Copy link
Copy Markdown
Collaborator

Sure, thank you very much for your attention and contribution. We will schedule a review for your PR and get back to you.

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.

2 participants