Files
openclaude/docs/local-system-info-egress-audit.md
YoVinchen 5af8acb2bb Checkpoint the full local bridge and audit work before telemetry removal
You asked for all local code to be committed before the broader telemetry-removal pass. This commit snapshots the current bridge/session ingress changes together with the local audit documents so the next cleanup can proceed from a stable rollback point.

Constraint: Preserve the exact local worktree state before the telemetry-removal refactor begins
Constraint: Avoid mixing this baseline snapshot with the upcoming telemetry deletions
Rejected: Fold these staged changes into the telemetry-removal commit | Would blur the before/after boundary and make rollback harder
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: Treat this commit as the pre-removal checkpoint when reviewing later telemetry cleanup diffs
Tested: Not run (baseline snapshot commit requested before the next cleanup pass)
Not-tested: Runtime, build, and typecheck for the staged bridge/session changes
2026-04-09 14:09:44 +08:00

16 KiB
Raw Permalink Blame History

本地系统信息外发审计报告

  • 审计时间: 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.idsession.idorganization.iduser.emailterminal.type 等发往配置的 OTLP endpoint。
  3. 目前未发现的自动采集项

    • 未发现自动读取并外发 MAC 地址、网卡列表、IP 地址、/etc/machine-id、BIOS/主板序列号、硬件 UUID、dmidecodeioregsystem_profiler 之类更敏感的硬件唯一标识。
  4. 额外重要发现

    • 这套代码不仅会外发“系统信息”,还会外发一部分“项目上下文”。
    • 典型例子包括: 当前工作目录、是否 git 仓库、当前分支、main 分支、git user.name、git status --short、最近 5 条提交、CLAUDE.md 内容、当前日期。

审计方法

本次审计主要做了两件事:

  1. 搜索本地系统/环境信息采集点。

    • 关键词包括 os.*process.platformprocess.archprocess.envhostname()userInfo()/etc/os-releaseunamegit statusgetCwd() 等。
  2. 搜索外发点并做数据流关联。

    • 关键词包括 axios.postfetchWebSocketanthropic.beta.messages.createDatadogevent_loggingtrusted_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 <hostname> · <platform> /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-648computeEnvInfo() 会构造环境块,包含:

    • Working directory
    • Is directory a git repo
    • Platform
    • Shell
    • OS Version
  2. src/constants/prompts.ts:651-709computeSimpleEnvInfo() 也会构造同类信息,且包含 Primary working directory

  3. src/context.ts:36-103getGitStatus() 会进一步读取:

    • 当前分支
    • main 分支
    • git config user.name
    • git status --short
    • 最近 5 条提交
  4. src/context.ts:116-149getSystemContext() 会把 gitStatus 注入系统上下文。

  5. src/context.ts:155-187getUserContext() 会把 CLAUDE.md 内容和当前日期放入用户上下文。

  6. src/utils/api.ts:437-446appendSystemContext() 会把 systemContext 拼到 system prompt。

  7. src/utils/api.ts:449-470prependUserContext() 会把 userContext 作为 <system-reminder> 前置到消息里。

  8. src/query.ts:449-450src/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 元信息。
  • 从数据敏感性看,cwdgit 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 定义了要采集的 EnvContextProcessMetrics 字段。

  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 表明 rhgit remote URL 的 SHA256 前 16 位哈希,不是明文 remote URL。

  8. src/services/analytics/datadog.ts:12-13 指向 Datadog endpointsrc/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_metadatauser_metadataevent_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-68FeedbackData 定义包含:

    • 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-2452src/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> · <platform>"

结论:

  • 这是 登录/设备注册链路,不是普通对话请求。
  • 这里出现了明确的 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 addripconfighostname 主要出现在 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% 抓包确认。
  • 如果你需要,我下一步可以继续补一版:
    • 运行时抓包建议
    • 外发域名清单
    • 按“默认开启 / 可关闭 / 必须用户触发”生成一张更适合合规审查的表