Skip to content

fix(offload): enable TLS verification by default; add env opt-out + CA path#42

Open
YOMXXX wants to merge 1 commit into
Tencent:mainfrom
YOMXXX:fix/offload-tls-verify
Open

fix(offload): enable TLS verification by default; add env opt-out + CA path#42
YOMXXX wants to merge 1 commit into
Tencent:mainfrom
YOMXXX:fix/offload-tls-verify

Conversation

@YOMXXX
Copy link
Copy Markdown

@YOMXXX YOMXXX commented May 18, 2026

Summary | 摘要

Fix CWE-295 (Improper Certificate Validation) in the offload backend client. Closes #8.

修复 #8 报告的 offload backend client TLS 校验绕过(CWE-295)。

Background | 背景

src/offload/backend-client.ts 之前在每次 HTTPS 请求中无条件传入 rejectUnauthorized: false

// before
const req = transport.request(
  {
    hostname: parsed.hostname,
    port: parsed.port || (isHttps ? 443 : 80),
    path: parsed.pathname + parsed.search,
    method: "POST",
    headers: reqHeaders,
    ...(isHttps ? { rejectUnauthorized: false } : {}),
  },

任何在网络路径上的 MITM 都能:

  • 读取 L1/L1.5/L2/L4 工具调用摘要 + 完整 task 历史
  • 读取 Authorization: Bearer <apiKey>
  • 读取 X-User-Id / X-Task-Id 身份头
  • 篡改 backend 响应 —— L1/L2/L4 输出会被写入用户数据目录,构成 memory poisoning 向量

src/core/store/tcvdb-client.ts 已经做对了(用 caPemPath 加载自签 CA)—— backend-client 的 rejectUnauthorized: false 是历史遗留 oversight。

Fix | 修复

将默认值回到 secure(用系统 trust store 做完整链校验),通过两个环境变量提供 opt-in:

环境变量 行为
TDAI_OFFLOAD_INSECURE_TLS=1 关闭 rejectUnauthorized。构造时打 loud warn,确保运维不会无意中带到生产。仅用于本地开发对接自签 backend。
TDAI_OFFLOAD_CA_PEM_PATH=<path> 加载自签 CA 证书,让自签 backend 在 不关闭校验 的前提下被信任。命名与 tcvdb-client.tscaPemPath 一致。

两个值都在 BackendClient constructor 内解析一次并缓存到 this.tlsOptions,请求 hot path 不再读 env,daemon 生命周期内的 TLS 立场稳定可审计。

CA 文件不存在 / 读不了时退回系统 trust store + warn,不会 让 daemon 启动失败。

Tests | 测试

新建 src/offload/__tests__/backend-client-tls.test.ts(7 cases):

  1. ✅ 默认(无 env)→ secure(不注入任何 TLS option)
  2. TDAI_OFFLOAD_INSECURE_TLS=1rejectUnauthorized: false + warn
  3. TDAI_OFFLOAD_INSECURE_TLS"1" 字面值("true"/"yes"/"0"/空/带空格)→ 忽略,保持 secure
  4. TDAI_OFFLOAD_CA_PEM_PATH=<readable> → 加载 CA 字节到 tlsOptions.ca,info 日志,不关校验
  5. TDAI_OFFLOAD_CA_PEM_PATH=<不存在> → warn + 退回系统 trust store,构造不抛
  6. ✅ 两个 env 同时设 → INSECURE 与 CA 都生效,操作员同时看到两条日志
  7. ✅ 构造时解析(后续修改 env 不影响已 new 出来的实例)
✓ npx vitest run src/offload  → 7/7 passed

Out of scope | 范围外

  • tcvdb-client.ts 的 TLS 处理风格统一(迁移到 undici Agent)—— 当前 backend-client 用原生 https 模块,重写 transport 风险大,保留原 transport 仅在 options 上加 TLS 字段
  • 配置项走 BackendClient constructor 参数 —— constructor 签名是 positional,加参数破坏 backward compat,env 路径更稳

DCO

Commit de35946Signed-off-by: 李冠辰 <liguanchen@xiaomi.com>

…A path

The offload backend client (src/offload/backend-client.ts) unconditionally
set rejectUnauthorized: false on every HTTPS request, fully bypassing TLS
certificate validation. Any MITM on the network path between the daemon and
the configured https://... offload backend could read or tamper with:

  - L1/L1.5/L2/L4 tool-call summaries and full task history
  - the Authorization: Bearer <apiKey> header
  - the X-User-Id / X-Task-Id identity headers

Backend responses (L1 summaries, L2 task graphs, L4 skills) are written to
the user's data directory, so a tampered response is a memory-poisoning
vector too.

This change reverts the default to "secure" (full chain validation against
the system trust store) and exposes two opt-ins via environment variables,
both resolved once at BackendClient construction:

  - TDAI_OFFLOAD_INSECURE_TLS=1
      Disable rejectUnauthorized. A loud warning is logged so the operator
      cannot accidentally ship this to production. Intended only for local
      development against a self-signed backend.

  - TDAI_OFFLOAD_CA_PEM_PATH=<path-to-ca.pem>
      Load a custom CA certificate so a self-signed backend can be trusted
      *without* disabling validation. Mirrors the caPemPath option on
      src/core/store/tcvdb-client.ts (which already gets this right).

A missing or unreadable CA file degrades gracefully to the system trust
store with a warning, so a misconfigured path cannot brick a running daemon.

Closes Tencent#8.

Tests: new src/offload/__tests__/backend-client-tls.test.ts — 7 cases
covering the secure default, INSECURE_TLS opt-in + warning, CA load
success / failure paths, both-set composition, and construction-time
resolution (subsequent env mutation does not retroactively affect the
existing instance).

Signed-off-by: 李冠辰 <liguanchen@xiaomi.com>
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.

[Security] Offload Backend Client disables TLS certificate verification (rejectUnauthorized: false)

1 participant