← 返回信息流
AI 资讯Hacker News·3 小时前

Grok Build CLI向xAI发送的数据揭秘

原标题:What xAI's Grok Build CLI Actually Sends to xAI

速览

本文详细分析了xAI推出的Grok Build CLI工具在实际使用中向xAI服务器发送了哪些数据,包括构建信息、环境变量等。这些发现可能影响开发者对数据隐私和工具透明度的关注。文章对于理解AI开发工具的数据行为具有重要意义。

AI 深度解读

背景

xAI 推出的官方编码 CLI 工具 grok(Gro​k Build)旨在帮助开发者通过终端与 Grok 模型交互、编写代码。然而,一位安全研究人员对 grok 的实际网络行为进行了可复现的逆向拆解,发现该工具在默认情况下会向 xAI 的服务器上传大量数据,包括用户本地 .env 文件中的密钥(secrets),以及整个 Git 仓库的完整内容(含历史记录)。该拆解基于 macOS Apple Silicon 平台、grok 0.2.93 版本,通过 mitmproxy 代理捕获流量,并使用伪造的“金丝雀”密钥仓库进行验证,未暴露真实凭据。研究结果已发布在 Hacker News 上,引发了对隐私与数据安全的广泛讨论。

核心内容

xAI 的官方 Grok Build CLI(grok)在普通消费者登录后,会执行三个值得精确记录的动作:

  1. 传输所有读取的文件内容(包括 .env 密钥文件)至 xAI,原样、无删节。该密钥出现在两个通道中:

    • 实时模型交互轮次:通过 POST /v1/responses 发送。
    • 会话状态(session_state)归档:通过 POST /v1/storage 上传并被接受(HTTP 200),该端点对应的二进制路由指向 grok-code-session-traces GCS bucket(见原文 §5)。
  2. 上传整个仓库——所有被跟踪文件的内容加上 Git 历史——独立于代理实际读取了什么。Grok 打包工作区并通过 POST /v1/storage 上传。直接证明:在一个真实代码库中,使用提示词“回复 OK,不要读取任何文件”,Grok 仍然将整个仓库作为 Git bundle 上传(POST /v1/storage → 200);克隆捕获的 bundle 可以恢复一个代理被告知不要打开的文件——src/_probe/never_read_canary.txt——其唯一标记原样存在,连同完整的 Git 历史(见附录 uploaded_repo.bundle)。该行为具有规模性:在一个 12 GB 的从未读取过的随机文件仓库中,/v1/storage 传输了 5.10 GiB,全部返回 HTTP 200(中途被截断),而模型交互通道仅移动了 192 KB——比例约为 27,800 倍,明确将上传行为指向代码库本身,而非读取的内容。没有任何存储上传失败;唯一的非 200 状态码是模型使用配额(402/429)和一次无关的 404,而非存储大小限制。

  3. 存储目的地是 Google Cloud Storage 的 grok-code-session-traces 存储桶(并非 AWS S3)——该名称以明文形式出现在二进制文件中以及捕获的 metadata.json 中(gs://grok-code-session-traces/…)。研究人员未在 CLI 的安装/快速入门材料中找到此机制(未做详尽文档审计,见原文 §7),该功能默认启用,且关闭“改进模型(Improve the model)”选项并不会禁用该上传(/v1/settings 仍返回 trace_upload_enabled: true;见原文 §6)。

以上所有发现均不证明 xAI 使用这些数据进行训练——这是一个策略问题(原文 §6 讨论)。但已证明的数据传输、接受和存储行为是确凿的。

安装与身份验证

  • 安装:curl -fsSL https://x.ai/cli/install.sh | bash~/.grok/bin/grok
  • 认证:首次启动打开浏览器 → 登录 X / SuperGrok(消费者账户,非 API 密钥)
  • 二进制身份(可复现):~/.grok/bin/grok -> ../downloads/grok-macos-aarch64,Mach-O 64-bit 可执行文件 arm64,版本 grok 0.2.93 (f00f96316d4b),SHA-256: 2a97ba675bd992aa9b981e2e83776460d94f469b510c0b8efe28b50d236d767c

上传机制

上传机制是一个第一方 Rust crate。在二进制文件上运行 strings 得到以下源路径和常量(可复现):

crates/codegen/xai-data-collector/src/gcs.rs
crates/codegen/xai-data-collector/src/storage_client.rs
crates/codegen/xai-data-collector/src/queue.rs
crates/codegen/xai-data-collector/src/file_access_tracker.rs
crates/codegen/xai-data-collector/src/circuit_breaker_observer.rs
crates/codegen/xai-grok-shell/src/upload/{gcs,turn,trace,manifest}.rs
grok-code-session-traces
storage.googleapis.com
"Uploading bytes to GCS via proxy"

网络捕获方法

  • 环境:macOS, Apple Silicon, grok 0.2.93, 2026年7月(原文日期)。
  • 安装 mitmproxy,生成 CA 证书,信任该证书。
  • 通过代理运行 Grok:HTTPS_PROXY=http://127.0.0.1:8080 SSL_CERT_FILE=~/.mitmproxy/mitmproxy-ca-cert.pem grok -p "<prompt>" --cwd <repo>
  • 使用 mitmdump 插件记录每个请求:方法、主机、路径、响应状态、请求字节大小;并保存 xAI 主机的请求体。
  • 对于阶段性的工件检查,在运行期间竞速复制 ~/.grok/upload_queue/*,然后 gzip -dc | tar -xO

金丝雀测试仓库

每个文件携带唯一标记,以便在捕获的流量中明确追踪。秘密文件 secrets.env / .env 内容:

API_KEY=CANARY7F3A9-SECRET-should-not-leave
DB_PASSWORD=CANARY7F3A9-DBPASS

声明:当 Grok 读取一个文件时,其内容会被传输至 xAI——序列化到 POST /v1/responses 模型交互体中,并打包到 session_state 归档中通过 POST /v1/storage 上传并被接受(HTTP 200)——文件内容未经任何删节。.env 文件像其他任何文件一样被发送。

有线工件:一个已解密的 48,070 字节的 POST cli-chat-proxy.grok.com/v1/responses 请求体(可通过嵌入的 "messages":[...]"model":"grok-4.5" JSON 识别为模型交互轮次)。其中包含完整的秘密文件内容(附录 secrets_responses_body.binsecret_verbatim.txt):

…API_KEY=CANARY7F3A9-SECRET-should-not-leave\nDB_PASSWORD=CANARY7F3A9-DBPASS\n…"model":"grok-4.5"…

可复现:grep -a "CANARY7F3A9-DBPASS" secrets_responses_body.bin → 匹配。所有六个文件标记(源码、逻辑、README

查看原文 →gist.github.com