# 本地系统信息外发审计报告 - 审计时间: 2026-04-03 - 审计对象: `/Users/yovinchen/project/claude` - 审计方式: 静态代码扫描 + 关键数据流人工追踪 - 说明: 本报告基于源码静态分析得出,未做运行时抓包或服务端行为验证。 ## 结论摘要 结论是: **存在“采集本地/环境信息并向外发送”的代码路径,而且其中一部分是默认链路。** 我把风险按类型拆开后,结论如下: 1. **默认会发生的外发** - 模型请求链路会把本地环境信息放进 system prompt / meta message 后发送给 Claude API。 - analytics/telemetry 链路会把平台、架构、Node 版本、终端、运行时、Linux 发行版、进程内存/CPU 指标等发送到 Datadog 和 Anthropic 1P 事件日志接口。 2. **用户显式触发后才会发生的外发** - Feedback / Transcript Share 会上传 transcript、平台信息、错误信息、最近 API 请求等。 - Remote Control / Bridge 会上传 `hostname`、本地目录、git 分支、git remote URL。 - Trusted Device 注册会上传 `hostname + platform` 组成的设备显示名。 - 可选 OpenTelemetry 在启用后会把 `user.id`、`session.id`、`organization.id`、`user.email`、`terminal.type` 等发往配置的 OTLP endpoint。 3. **目前未发现的自动采集项** - 未发现自动读取并外发 MAC 地址、网卡列表、IP 地址、`/etc/machine-id`、BIOS/主板序列号、硬件 UUID、`dmidecode`、`ioreg`、`system_profiler` 之类更敏感的硬件唯一标识。 4. **额外重要发现** - 这套代码不仅会外发“系统信息”,还会外发一部分“项目上下文”。 - 典型例子包括: 当前工作目录、是否 git 仓库、当前分支、main 分支、git user.name、`git status --short`、最近 5 条提交、`CLAUDE.md` 内容、当前日期。 ## 审计方法 本次审计主要做了两件事: 1. 搜索本地系统/环境信息采集点。 - 关键词包括 `os.*`、`process.platform`、`process.arch`、`process.env`、`hostname()`、`userInfo()`、`/etc/os-release`、`uname`、`git status`、`getCwd()` 等。 2. 搜索外发点并做数据流关联。 - 关键词包括 `axios.post`、`fetch`、`WebSocket`、`anthropic.beta.messages.create`、`Datadog`、`event_logging`、`trusted_devices`、`/v1/environments/bridge`、`/v1/sessions` 等。 ## 发现清单 | 编号 | 链路 | 是否默认 | 外发内容 | 目标位置 | 结论 | | --- | --- | --- | --- | --- | --- | | F1 | 模型请求 system prompt / user context | 是 | cwd、平台、shell、OS 版本、git 状态、git 用户、最近提交、`CLAUDE.md`、日期 | Claude API | 已确认 | | F2 | Datadog analytics | 是 | 平台、架构、Node 版本、终端、运行时、Linux 发行版/内核、进程 CPU/内存、repo remote hash | Datadog | 已确认 | | F3 | Anthropic 1P event logging | 是 | 与 F2 类似,外加 user/account/org 元数据与 process blob | `https://api.anthropic.com/api/event_logging/batch` | 已确认 | | F4 | GrowthBook remote eval | 大概率是 | deviceId、sessionId、platform、org/account、email、版本、GitHub Actions 元数据 | `https://api.anthropic.com/` 上的 GrowthBook 接口 | **推断成立概率高** | | F5 | Feedback | 否,用户触发 | platform、terminal、是否 git、transcript、raw transcript、errors、lastApiRequest | `https://api.anthropic.com/api/claude_cli_feedback` | 已确认 | | F6 | Transcript Share | 否,用户触发 | platform、transcript、subagent transcripts、raw transcript JSONL | `https://api.anthropic.com/api/claude_code_shared_session_transcripts` | 已确认 | | F7 | Remote Control / Bridge | 否,功能触发 | hostname、directory、branch、git_repo_url、session context | `/v1/environments/bridge`、`/v1/sessions` | 已确认 | | F8 | Trusted Device | 否,登录/设备注册 | `Claude Code on · ` | `/api/auth/trusted_devices` | 已确认 | | F9 | OpenTelemetry | 否,需启用 | user/session/account/email/terminal + OTEL 检测到的 OS/host arch | 配置的 OTLP endpoint | 已确认 | | F10 | `/insights` 内部上传 | 非外部版默认不可用 | username、报告文件 | S3 | 已确认,且 `ant-only` | ## 详细分析 ### F1. 默认模型请求链路会外发本地环境和项目上下文 证据链如下: 1. `src/constants/prompts.ts:606-648` 的 `computeEnvInfo()` 会构造环境块,包含: - `Working directory` - `Is directory a git repo` - `Platform` - `Shell` - `OS Version` 2. `src/constants/prompts.ts:651-709` 的 `computeSimpleEnvInfo()` 也会构造同类信息,且包含 `Primary working directory`。 3. `src/context.ts:36-103` 的 `getGitStatus()` 会进一步读取: - 当前分支 - main 分支 - `git config user.name` - `git status --short` - 最近 5 条提交 4. `src/context.ts:116-149` 的 `getSystemContext()` 会把 `gitStatus` 注入系统上下文。 5. `src/context.ts:155-187` 的 `getUserContext()` 会把 `CLAUDE.md` 内容和当前日期放入用户上下文。 6. `src/utils/api.ts:437-446` 的 `appendSystemContext()` 会把 `systemContext` 拼到 system prompt。 7. `src/utils/api.ts:449-470` 的 `prependUserContext()` 会把 `userContext` 作为 `` 前置到消息里。 8. `src/query.ts:449-450`、`src/query.ts:659-661` 把这两部分上下文真正交给模型调用。 9. `src/services/api/claude.ts:3213-3236` 会把 `systemPrompt` 序列化为 API 文本块,`src/services/api/claude.ts:1822-1832` 通过 `anthropic.beta.messages.create(...)` 发出请求。 结论: - **这是默认链路**,不是用户额外点击“上传”后才发生。 - 外发的不只是主机 OS 信息,还包括当前项目目录和 git 元信息。 - 从数据敏感性看,`cwd`、`git user.name`、最近提交标题、`CLAUDE.md` 都可能包含组织或项目标识。 ### F2. 默认 Datadog analytics 会外发环境与进程指标 证据链如下: 1. `src/main.tsx:416-430` 会在启动早期初始化用户/上下文/analytics gate。 2. `src/main.tsx:943-946` 会初始化 sinks,从而启用 analytics sink。 3. `src/services/analytics/metadata.ts:417-467` 定义了要采集的 `EnvContext` 和 `ProcessMetrics` 字段。 4. `src/services/analytics/metadata.ts:574-637` 实际构造环境信息,包含: - `platform` / `platformRaw` - `arch` - `nodeVersion` - `terminal` - `packageManagers` - `runtimes` - `isCi` - `isClaudeCodeRemote` - `remoteEnvironmentType` - `containerId` - `github actions` 相关字段 - `wslVersion` - `linuxDistroId` - `linuxDistroVersion` - `linuxKernel` - `vcs` 5. `src/services/analytics/metadata.ts:648-678` 采集进程指标,包含: - `uptime` - `rss` - `heapTotal` - `heapUsed` - `external` - `arrayBuffers` - `constrainedMemory` - `cpuUsage` - `cpuPercent` 6. `src/services/analytics/metadata.ts:701-739` 会把这些信息合并进每个 analytics event,并附加 `rh`。 7. `src/utils/git.ts:329-337` 表明 `rh` 是 **git remote URL 的 SHA256 前 16 位哈希**,不是明文 remote URL。 8. `src/services/analytics/datadog.ts:12-13` 指向 Datadog endpoint,`src/services/analytics/datadog.ts:108-115` 通过 `axios.post(...)` 发送。 结论: - **Datadog 默认是活跃链路**,除非被隐私设置或 provider 条件关闭。 - 这条链路没有看到把 `cwd`、源码正文、文件路径直接送去 Datadog;它主要发送环境维度与运行指标。 - repo remote 不是明文发出,而是哈希值。 ### F3. 默认 Anthropic 1P event logging 也会外发环境与身份元数据 证据链如下: 1. `src/services/analytics/firstPartyEventLogger.ts:141-177` 表明 1P event logging 默认启用时,会把 `core_metadata`、`user_metadata`、`event_metadata` 一起记录。 2. `src/services/analytics/firstPartyEventLoggingExporter.ts:114-120` 指定 1P 上报 endpoint 为: - `https://api.anthropic.com/api/event_logging/batch` - 或 staging 对应路径 3. `src/services/analytics/firstPartyEventLoggingExporter.ts:587-609` 表明最终通过 `axios.post(this.endpoint, payload, ...)` 发送。 4. `src/services/analytics/metadata.ts:796-970` 表明在 1P 格式化阶段,以下字段会进入上报内容: - `platform/platform_raw` - `arch` - `node_version` - `terminal` - `package_managers` - `runtimes` - `is_ci` - `is_github_action` - `linux_distro_id` - `linux_distro_version` - `linux_kernel` - `vcs` - `process` base64 blob - `account_uuid` - `organization_uuid` - `session_id` - `client_type` 结论: - **这也是默认链路**。 - 与 Datadog 相比,1P event logging 能接收更完整的内部结构化元数据。 ### F4. GrowthBook 很可能会把本地/身份属性发到远端做特性分流 证据链如下: 1. `src/services/analytics/growthbook.ts:454-484` 构造了 `attributes`,包含: - `id` / `deviceID` - `sessionId` - `platform` - `apiBaseUrlHost` - `organizationUUID` - `accountUUID` - `userType` - `subscriptionType` - `rateLimitTier` - `firstTokenTime` - `email` - `appVersion` - `githubActionsMetadata` 2. `src/services/analytics/growthbook.ts:526-536` 使用: - `apiHost` - `attributes` - `remoteEval: true` 创建 `GrowthBook` client。 判断: - 由于真正的 HTTP 逻辑在第三方库内部,不在本仓库源码里直接展开,所以这里我不能把“已确认发送”说死。 - 但从 `attributes + apiHost + remoteEval: true` 的组合看,**高概率**存在把这些属性发送到 GrowthBook 后端做远程特性评估的行为。 - 这一条应标记为 **推断**,但可信度较高。 ### F5. Feedback 会在用户触发时上传平台、转录、错误和最近请求 证据链如下: 1. `src/components/Feedback.tsx:54-68` 的 `FeedbackData` 定义包含: - `platform` - `gitRepo` - `version` - `transcript` - `rawTranscriptJsonl` 2. `src/components/Feedback.tsx:206-224` 实际组装 `reportData` 时还加入: - `terminal` - `errors` - `lastApiRequest` - `subagentTranscripts` 3. `src/components/Feedback.tsx:543-550` 发送到 `https://api.anthropic.com/api/claude_cli_feedback`。 结论: - 这是 **用户显式触发** 的上传,不属于静默默认遥测。 - 但数据面比普通 analytics 大得多,包含对话转录和最近 API 请求内容。 ### F6. Transcript Share 会在用户触发时上传 transcript 和平台 证据链如下: 1. `src/components/FeedbackSurvey/submitTranscriptShare.ts:37-70` 采集: - `platform` - `transcript` - `subagentTranscripts` - `rawTranscriptJsonl` 2. `src/components/FeedbackSurvey/submitTranscriptShare.ts:87-94` 发送到 `https://api.anthropic.com/api/claude_code_shared_session_transcripts`。 结论: - 这是 **显式分享链路**。 - 风险面和 Feedback 类似,重点在 transcript 内容,而不是系统信息本身。 ### F7. Remote Control / Bridge 会上传 hostname、目录、分支、git remote URL 证据链如下: 1. `src/bridge/bridgeMain.ts:2340-2452` 与 `src/bridge/bridgeMain.ts:2874-2909` 都会在 bridge 启动时读取: - `branch` - `gitRepoUrl` - `machineName = hostname()` - `dir` 2. `src/bridge/initReplBridge.ts:463-505` 也会把 `hostname()`、branch、gitRepoUrl 传入 bridge core。 3. `src/bridge/bridgeApi.ts:142-183` 注册环境时 POST 到 `/v1/environments/bridge`,字段包括: - `machine_name` - `directory` - `branch` - `git_repo_url` - `max_sessions` - `worker_type` 4. `src/bridge/createSession.ts:77-136` 创建 session 时还会把 git 仓库上下文放进 `session_context`,包括: - 规范化后的 repo URL - revision / branch - owner/repo - model 结论: - 这是 **功能型外发**,不是无条件默认发生。 - 但一旦启用 Remote Control,它会把本地主机名和项目标识信息发送出去。 ### F8. Trusted Device 会上传 hostname + platform 证据链如下: 1. `src/bridge/trustedDevice.ts:145-159` 会向 `${baseUrl}/api/auth/trusted_devices` 发送: - `display_name: "Claude Code on · "` 结论: - 这是 **登录/设备注册链路**,不是普通对话请求。 - 这里出现了明确的 `hostname()` 外发。 ### F9. OpenTelemetry 是可选链路,但一旦启用也会对外发送本地属性 证据链如下: 1. `src/utils/telemetry/instrumentation.ts:324-325` 表明只有 `CLAUDE_CODE_ENABLE_TELEMETRY=1` 时才启用。 2. `src/utils/telemetry/instrumentation.ts:458-510` 会组装 OTEL resource,包含: - service/version - WSL version - OS detector 结果 - host arch detector 结果 - env detector 结果 3. `src/utils/telemetry/instrumentation.ts:575-607` 会初始化 log exporter 并对外发送。 4. `src/utils/telemetryAttributes.ts:29-68` 还会加入: - `user.id` - `session.id` - `app.version` - `organization.id` - `user.email` - `user.account_uuid` - `user.account_id` - `terminal.type` 结论: - 这是 **可选链路**,默认不是强制开启。 - 但如果启用并配置了 OTLP endpoint,确实会把本地身份/终端/会话属性发到外部。 ### F10. `/insights` 还存在内部版上传链路 证据链如下: 1. `src/commands/insights.ts:2721-2736` 报告元数据包含: - `username` - 生成时间 - 版本 - 远程 homespace 信息 2. `src/commands/insights.ts:3075-3098` 会在 `process.env.USER_TYPE === 'ant'` 时尝试上传 HTML 报告到 S3。 结论: - 这是 **内部版 ant-only** 逻辑,不应算外部公开版本默认行为。 - 但从源码角度,确实存在上传用户名和报告的链路。 ## 未发现项 本次静态审计中,**没有发现**以下类型的自动采集/外发实现: - `os.networkInterfaces()` - `os.userInfo()` 用于遥测/外发 - `/etc/machine-id` - `node-machine-id` - `dmidecode` - `ioreg` - `system_profiler` - `wmic bios` - `getmac` - `ifconfig` / `ip addr` / `ipconfig /all` 被程序主动执行用于遥测 - MAC 地址、IP 地址、硬件序列号、主板 UUID、BIOS UUID 等硬件唯一标识 补充说明: - 搜到的 `ip addr`、`ipconfig`、`hostname` 主要出现在 Bash/PowerShell 工具的只读命令校验规则里,不是程序自身自动采集再上报。 - `hostname()` 的真实外发点主要集中在 Remote Control / Trusted Device。 ## 开关与缓解建议 ### 1. 如果你的目标是关闭默认 analytics/telemetry 源码里明确支持以下限制: - `src/utils/privacyLevel.ts:1-55` - `src/services/analytics/config.ts:11-26` 建议: - 设置 `DISABLE_TELEMETRY=1` - 会进入 `no-telemetry` - Datadog / 1P analytics 会被关闭 - 设置 `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1` - 会进入 `essential-traffic` - 非必要网络流量会被进一步压缩 ### 2. 如果你的目标是避免把本地目录和 git 信息送入模型 需要重点关注默认 prompt 链路,因为这部分不是传统“遥测”,而是模型上下文本身。 缓解思路: - 在不敏感目录中运行,而不是直接在真实业务仓库根目录运行 - 避免在 `git user.name`、commit message、`CLAUDE.md` 中放入敏感标识 - 禁用或清理 `CLAUDE.md` - 不启用 Remote Control / Bridge / Transcript Share / Feedback ### 3. 如果你的目标是避免 hostname 外发 避免使用: - Remote Control / Bridge - Trusted Device 注册 / 某些登录设备绑定流程 ## 最终判断 从“是否采集本地系统信息并向外发送”这个问题本身看,答案是: **是,存在,并且不止一条。** 但需要区分严重程度: - **默认自动发生** 的,主要是: - 模型请求中的环境/项目上下文 - analytics 中的环境/进程元数据 - **需要用户显式动作或特定功能开启** 才发生的,主要是: - Feedback / Transcript Share - Remote Control / Bridge - Trusted Device - OpenTelemetry - ant-only `/insights` - **未发现** 自动采集 MAC/IP/硬件序列号/机器唯一硬件 ID 的实现。 ## 审计局限 - 本报告只基于本仓库源码,不包含第三方依赖内部实现的完全展开。 - 因此 GrowthBook `remoteEval` 被标为“高概率推断”,不是 100% 抓包确认。 - 如果你需要,我下一步可以继续补一版: - 运行时抓包建议 - 外发域名清单 - 按“默认开启 / 可关闭 / 必须用户触发”生成一张更适合合规审查的表