fix(gateway): harden CORS / Host header / startup safety#1
Closed
YOMXXX wants to merge 1 commit into
Closed
Conversation
PR Tencent#7 引入的 Gateway HTTP 层有三处 critical 安全缺陷: 1. CORS 硬编码 Access-Control-Allow-Origin: * 且无条件允许 Authorization 头, 与 README 描述(默认禁用 CORS)矛盾。 2. handleRequest 不校验 Host header,配合 CORS * 形成 DNS rebinding 攻击面: 攻击者控制的域名 + 短 TTL DNS → 浏览器 JS 解析为 127.0.0.1 → fetch 通过。 3. server.ts 自带的 main() 入口(`tsx src/gateway/server.ts` 直跑)绕过 cli.ts 的 assertSafeHost() 与 loadTokenFromFile(),导致 host 校验与 token 文件加载被跳过;Hermes backward-compat(无 token)模式下 daemon 裸奔。 修复: - CORS 改为 opt-in:仅当 TDAI_GATEWAY_CORS_ORIGIN 显式设置时下发对应 Origin 的 CORS 头并 ack OPTIONS preflight;默认状态 OPTIONS 不再绕过 Bearer auth。 - Host header 白名单:handleRequest 前置校验,剥离端口/IPv6 括号后必须在 {127.0.0.1, localhost, ::1, ::ffff:127.0.0.1};TDAI_GATEWAY_ALLOW_REMOTE=1 时跳过校验,与现有 assertSafeHost 的 opt-in 语义一致。 - 抽 assertSafeHost / loadTokenFromFile 到 server.ts 作为 export helper (applyStartupSafety)。cli.ts main() 与 server.ts main() 都调用同一段, 两条启动路径共用同一段安全门。 测试:auth.test.ts 从 14 个 case 扩到 31 个,新增 CORS opt-in / Host 白名单 / TDAI_GATEWAY_ALLOW_REMOTE 跳过 的回归矩阵。cc-plugin 测试 55/55 通过无回归。 Signed-off-by: 李冠辰 <liguanchen@xiaomi.com>
Owner
Author
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.
Description | 描述
PR Tencent#7 评审过程中扫到 TDAI Gateway HTTP 层有三处 CORS / Host / startup 安全缺陷,独立拆出此 PR 以便 cc 集成 (PR Tencent#7) 与本次安全加固分别评审 / 合并。
This PR hardens three CORS / Host / startup-safety holes in TDAI Gateway surfaced during a security review of PR Tencent#7. Split out so the cc-integration feature and the security fix can land independently.
Depends on | 依赖
⏳ Depends on Tencent#7.
src/gateway/cli.tsandsrc/gateway/__tests__/auth.test.tsare introduced in Tencent#7. Base is currently set tofeat/claude-code-plugin; will retarget tomainonce Tencent#7 lands.依赖 Tencent#7。本 PR 涉及的
src/gateway/cli.ts与src/gateway/__tests__/auth.test.ts都是 Tencent#7 引入的文件,base 现在指向feat/claude-code-plugin;Tencent#7 合并后将切到main。Fixes | 修复
1. CORS hardcoded
Access-Control-Allow-Origin: *(src/gateway/server.ts:178-180)handleRequest无条件下发Access-Control-Allow-Origin: *+ 允许Authorization头。README 描述为"默认禁用 CORS",但实际代码无条件启用——与文档矛盾。配合 Tencent#2(Host 不校验)与 Tencent#3(main 入口不走 safety gate)/ Hermes backward-compat no-token 模式,恶意浏览器页面通过 DNS rebinding 可直接调用 daemon 数据端点。修复:CORS 改为 opt-in:仅当
TDAI_GATEWAY_CORS_ORIGIN显式设置时才下发对应 Origin 的 CORS 头;OPTIONS preflight 不再默认返回 204,落入正常路由 → Bearer auth 拦截。2. Host header unvalidated (
src/gateway/server.ts:172-174)req.headers.host不校验,配合 #1 形成 DNS rebinding 攻击面:攻击者域名短 TTL DNS 重定向到127.0.0.1→ 受害者浏览器 JS 发起 fetch → daemon 接受。修复:
handleRequest在路由前校验 Host header,剥离端口/IPv6 括号后必须在{127.0.0.1, localhost, ::1, ::ffff:127.0.0.1}集合内,否则 403。TDAI_GATEWAY_ALLOW_REMOTE=1opt-in 时跳过——与assertSafeHost()现有 opt-in 语义一致。3.
server.ts main()bypassescli.tssafety (src/gateway/server.ts:478-499)tsx src/gateway/server.ts直跑触发 server.ts 自带的main(),不调用cli.ts的assertSafeHost()+loadTokenFromFile(),导致 host 校验与 token 文件加载被跳过;Hermes backward-compat(无 token)模式下 daemon 裸奔。修复:抽
assertSafeHost/loadTokenFromFile到src/gateway/server.ts作为 export helper(applyStartupSafety)。cli.ts main() 与 server.ts main() 都调用同一段,两条启动路径共用同一段安全门。Self-test | 自测
npx vitest run src/gateway→ 31/31 (扩展自 14/14;+17 新 case 覆盖 CORS opt-in、Host 白名单、TDAI_GATEWAY_ALLOW_REMOTEopt-in)npm run test:cc-plugin -- --run→ 55/55 (no regression)applyStartupSafety()调用点人工验证:cli.ts main() 与 server.ts main() 均调用Out of scope | 范围外
PR Tencent#7 评审过程中还发现以下 High/Medium 项,作为 follow-up 单独处理:
stat()+readFile()TOCTOU (symlink swap)process.ppid作为 cc PID(shell wrapper 下不正确)parseJsonBody无 size limitDCO
Commit
c0a750e带Signed-off-by: 李冠辰 <liguanchen@xiaomi.com>。