跳转到内容
OmniRoute source

Socket.dev / supply-chain finding attestation (中文 (简体))

源文件:

  • src/mitm/cert/install.ts — 公开的 installCert() / uninstallCert(), 以及各平台对应的 installCertWindows/Mac/Linux。
  • src/mitm/systemCommands.ts — 安装路径使用的共享 execFile / spawn / PowerShell 辅助函数。

触发条件:用户在本地仪表板的 /dashboard/cli-tools/mitm 中点击“启用 MITM 代理”。该路由仅允许通过环回地址访问 — 请参阅 CLAUDE.md 中的硬性规则 #17,以及 src/server/authz/routeGuard.ts::isLocalOnlyPath()。通过隧道泄露的 JWT 无法触发此代码路径。

执行的特权操作(按平台):

操作系统 命令
Windows 通过 UAC 执行 certutil -addstore Root <cert>
macOS sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain <cert>
Linux sudo cp <cert> <distro-trust-dir> + sudo update-ca-certificates(Debian)/ sudo update-ca-trust(RHEL/SUSE)
Linux+Firefox/Chromium 通过 certutil -d sql:<profile> 更新各配置文件对应的 NSS 数据库

这些命令与 mitmproxy、Charles Proxy、Fiddler 和 Caddy 所使用的命令相同。OmniRoute 中存在这些命令的事实记录于 docs/security/STEALTH_GUIDE.md。

v3.8.6 缓解措施:

  • runElevatedPowerShell() 不再使用 -EncodedCommand <base64utf16le>。 提权载荷会写入每次调用专用的临时 .ps1 文件(模式为 0o600, 位于私有 mkdtempSync 目录中),并通过 -File 引用。 该文件会在 finally 中取消链接。这样便移除了 Socket.dev 的 AI 分类器所标记的典型 PowerShell base64 提权特征。
  • installCertWindows 包含一个指向本文档的内联 SECURITY-AUDITOR-NOTE: 块。

保留原因:MITM 代理是一项已有文档说明的功能,相关文档包括 docs/security/STEALTH_GUIDE.md 和 docs/frameworks/MITM-PROXY.md。移除 该功能会破坏代理桥接功能集。


§2 — Zed 凭据导入(app/api/providers/zed/import/route.js)

Section titled “§2 — Zed 凭据导入(app/api/providers/zed/import/route.js)”

源文件:

  • src/app/api/providers/zed/discover/route.ts (v3.8.6 中新增)
  • src/app/api/providers/zed/import/route.ts
  • src/lib/zed-oauth/keychain-reader.ts
  • src/lib/zed-oauth/credentialFingerprint.ts (v3.8.6 中新增)

触发方式:用户在本地仪表板的 Providers 页面中点击“从 Zed 导入”。该端点受 requireManagementAuth 保护。Zed 编辑器本身会使用已有文档说明的服务名称,将其提供者 API 密钥写入操作系统钥匙串——参见 https://zed.dev/docs/ai/llm-providers。

v3.8.5 的行为(Socket.dev 标记的版本):

POST /import 会发现凭据,并在单次往返中将其自动保存到本地 SQLite 存储。没有逐账户确认,也没有指纹,只有“找到 N 个令牌,已全部导入。”

v3.8.6 缓解措施——两步确认:

  1. POST /api/providers/zed/discover 返回 { candidates: [{ provider, service, account, fingerprint }] }。原始 令牌绝不会被传输。指纹为 sha256(service|account|token).slice(0,16)。
  2. 仪表板呈现候选项列表,操作员选择要导入的项目,然后将 { confirmedAccounts: [{ service, account, fingerprint }] } 发送到 POST /api/providers/zed/import。
  3. 导入端点会在服务器上重新读取钥匙串,并按 (service, account, fingerprint) 进行筛选。被篡改或重放的 discover 响应无法诱使导入端点保存无关令牌——如果实时令牌在 discover 之后发生变化,其指纹将不再匹配,因此该凭据会被跳过。

环境变量标志 OMNIROUTE_ZED_IMPORT_LEGACY_ONE_STEP=true 可为尚未更新自动化流程的操作员保留 v3.8.5 的行为。该标志将在 v3.9 中移除。

保留该功能的原因:对于已经使用 Zed,并希望将其提供者密钥同步到 OmniRoute、同时避免重新粘贴密钥的用户,Zed 导入是最友好的上手方式。


§3 — execFile / spawn / 提权 PowerShell(21843.js)

Section titled “§3 — execFile / spawn / 提权 PowerShell(21843.js)”

源文件:src/mitm/systemCommands.ts。

被标记的原因:该代码块重新导出了 execFileWithPassword、runElevatedPowerShell 以及共享的 quotePowerShell 辅助函数。Socket.dev 的 AI 分类器将它们视为通用的“主机执行 + 权限提升工具包”。在 OmniRoute 中,它们仅用于 MITM 证书安装路径(§1),以及由 execFileWithPassword 执行 sudo 命令。

v3.8.6 缓解措施:

  • 重构 runElevatedPowerShell(参见 §1)。
  • 在 runElevatedPowerShell 和 execFileWithPassword 两处内联添加 SECURITY-AUDITOR-NOTE: 块,用于记录已列入允许列表的调用方和固定的可执行文件列表。
  • execFileWithPassword 的 spawn() 调用带有 nosemgrep 标记,其中包含允许该辅助函数接收的可执行文件允许列表——用户输入不存在任何通向 finalCommand/finalArgs 的路径。

§4 / §6 — 9router 服务监管器(api/services/9router/{start,restart}/route.js)

Section titled “§4 / §6 — 9router 服务监管器(api/services/9router/{start,restart}/route.js)”

源文件:

  • src/app/api/services/9router/_lib.ts — 监管器工厂。
  • src/app/api/services/9router/{start,stop,restart,status,install,update,auto-start}/route.ts。
  • src/lib/services/ServiceSupervisor.ts — 通用的进程生成 / 健康状态轮询 / 日志缓冲功能。

触发方式:用户在本地仪表板的嵌入式服务页面中点击“安装”/“启动”。

现有保护措施:

  • 根据 src/server/authz/routeGuard.ts(硬性规则 #17),所有 /api/services/* 路由均为 LOCAL_ONLY。环回地址限制会在任何身份验证检查之前执行——即使 JWT 泄露,也无法访问这些路由。
  • 9router 数据库行初始化为 status='not_installed', auto_start=0(参见 src/lib/db/migrations/071_services.sql:19)。该服务不会在首次启动时运行。
  • spawn() 使用由 src/lib/services/installers/ninerouter.ts 中的 resolveSpawnArgs(apiKey, PORT) 返回的二进制文件路径调用,该路径来自受支持二进制文件的固定允许列表。
  • Stdout/stderr 缓存在内存中(上限为 5 MB,参见 _lib.ts)——除非用户在仪表板中启用日志记录,否则不会写入磁盘。

v3.8.6 缓解措施:无功能变更。最小构建配置 (OMNIROUTE_BUILD_PROFILE=minimal)会将 src/lib/services/installers/ninerouter.ts 替换为存根,供希望从软件包中物理移除特权路径的用户使用。

保留该功能的原因:9router 是一个可选的、可在本地安装的配套服务(类似于 WordPress 风格的插件)——必须严格选择加入。


§5 — OmniRoute Cloud Sync 凭据回写(api/keys/[id]/route.js)

Section titled “§5 — OmniRoute Cloud Sync 凭据回写(api/keys/[id]/route.js)”

源文件:

  • src/lib/cloudSync.ts — syncToCloud() / updateLocalTokens()。
  • src/app/api/keys/[id]/route.ts — 调用 syncKeysToCloudIfEnabled()。

触发条件:isCloudEnabled() 返回 true(通过控制面板设置),并且 已配置 CLOUD_URL。如果两者均关闭,则不会向 Cloud 端点发起出站网络调用。

v3.8.5 的行为(Socket.dev 正确捕获的漏洞):

当 cloudUpdatedAt > localUpdatedAt 时,updateLocalTokens() 会使用 Cloud 响应中的值覆盖 accessToken、refreshToken 和 providerSpecificData。没有 HMAC、没有签名、没有校验和。配置错误或恶意的 CLOUD_URL(或信道上的中间人攻击者)可以悄无声息地替换提供者的 OAuth 令牌。

v3.8.6 缓解措施:

  1. HMAC 验证:verifyCloudSignature(rawBody, sigHeader) 在解析 JSON 之前检查 X-Cloud-Sig 标头(HMAC-SHA256(OMNIROUTE_CLOUD_SYNC_SECRET, rawBody))。如果已设置密钥,则必须提供签名。如果未设置(旧版模式), 系统会记录警告并接受响应——从 v3.9 起将强制要求配置密钥。
  2. 敏感字段显式启用:仅当 OMNIROUTE_CLOUD_SYNC_SECRETS=true 时,才会覆盖 accessToken / refreshToken / providerSpecificData。默认模式仅同步 非凭据元数据(expiresAt、status、lastError*、 rateLimitedUntil、updatedAt)。对于依赖远程令牌同步的用户而言, 这是一项破坏性变更——他们必须显式选择启用。

保留此功能的原因:Cloud Sync 是 OmniRoute Cloud 租户集中管理团队凭据的 唯一方式。此修复使威胁模型更加明确: “服务器签名,客户端验证,运维人员选择启用。”


需要对 Socket 友好的构建产物时,请使用以下命令构建:

终端窗口
OMNIROUTE_BUILD_PROFILE=minimal npm run build

webpack 的 NormalModuleReplacementPlugin 会将四个模块别名映射到存根:

模块 存根
src/mitm/cert/install.ts src/mitm/cert/install.stub.ts
src/lib/zed-oauth/keychain-reader.ts src/lib/zed-oauth/keychain-reader.stub.ts
src/lib/cloudSync.ts src/lib/cloudSync.stub.ts
src/lib/services/installers/ninerouter.ts src/lib/services/installers/ninerouter.stub.ts

每个存根都导出相同的接口,但每个函数在运行时都会抛出 featureDisabledError(name)。依赖已禁用模块的路由会返回 HTTP 503 以及清晰的消息,而不会激活敏感代码路径。

生成的捆绑包将以 omniroute-secure 的名称发布。有关发布流程,请参阅 docs/ops/PUBLISHING_SECURE.md。


从长远来看,我们计划将 npm 包拆分为可单独审计的模块。有关跟踪此事项的 issue,请参阅 GitHub issue 跟踪器中的 v4 里程碑。


OmniRoute 源码 (a58000c7685f)

HagiCode

HagiCode 是一套智能体编码工作台:结构化工作流、多 Agent 并行执行与 Hero Dungeon 视图,把想法变成真正交付的软件。

让想法更快变成好用的软件,让智能编码更聪明、更高效,也更有趣。

HagiCode 浅色主题主界面截图
  • Smart结构化工作流将意图转化为从想法到交付的可执行路径。
  • Efficient多 Agent 工作流让调研、实现与审阅并行推进。
  • FunHero Dungeon 让长时间编码协作更直观、更有参与感。
访问 HagiCode