1 ポイント 投稿者 GN⁺ 4 시간 전 | 1件のコメント | WhatsAppで共有
  • grok 0.2.93のネットワークトラフィックを直接キャプチャした結果、Grok Buildは読み取ったファイルをマスキングなしで送信し、session_stateとして保存していたほか、テスト用の.env秘密値も2つの経路にそのまま含めていた
  • モデル要求でエージェントが読んだファイルを送るのとは別に、すべての追跡ファイルとGit履歴を含むリポジトリ全体がgit bundleとしてアップロードされ、開かないよう指定したファイルも原文のまま復元できた
  • 12GBのランダムファイルリポジトリでは、/v1/responses要求は合計192KBだった一方、/v1/storageの送信量はキャプチャ中断時点までに5.10GiBに達し、約27,800倍の差があり、すべての保存要求がHTTP 200を返した
  • アップロード先はGoogle Cloud Storageの**grok-code-session-tracesバケット**で、「Improve the model」をオフにしてもtrace_upload_enabled: trueupload_enabled: trueが維持され、リポジトリ全体のアップロードが継続した
  • 実験はデータの送信・受理・保存を立証するが、モデル学習に使われたかどうかは確認できておらず.gitignoreファイルやすべてのアカウント・設定の組み合わせも試していないため、結果は2026年7月の特定バージョンに限られる

テスト対象と分析範囲

  • 対象は一般消費者アカウントでログインしたxAI公式のGrok Build CLI
    • インストール先は~/.grok/bin/grok
    • ブラウザでXまたはSuperGrokアカウントを使って認証し、APIキーは使用しない
    • テストしたバイナリはApple Silicon向けのgrok 0.2.93 (f00f96316d4b)
    • SHA-256は2a97ba675bd992aa9b981e2e83776460d94f469b510c0b8efe28b50d236d767c
  • バイナリ文字列から独自のRustアップロード構成要素とストレージ関連の定数を確認
    • crates/codegen/xai-data-collector/src/gcs.rs
    • storage_client.rs, queue.rs, file_access_tracker.rs, circuit_breaker_observer.rs
    • xai-grok-shell/src/upload/{gcs,turn,trace,manifest}.rs
    • grok-code-session-traces, storage.googleapis.com, Uploading bytes to GCS via proxy
  • すべてのキャプチャはテスト実施者のコンピュータとそのトラフィックのみを対象とし、リポジトリには実際の資格情報の代わりに固有のcanary文字列を入れた

再現とトラフィックキャプチャ方法

  • macOS Apple SiliconでmitmproxyのCAをログインキーチェーンに信頼済み証明書として追加し、HTTPS_PROXYSSL_CERT_FILEを設定してGrokのHTTPS要求をキャプチャした
  • Grokはこの構成で**証明書ピンニング(certificate pinning)**によるキャプチャ遮断を行わなかった
  • mitmdumpアドオンで要求ごとのメソッド、ホスト、パス、応答ステータス、要求バイト数を記録し、xAIホスト宛ての要求本文を保存した
  • ~/.grok/upload_queue/*を実行中にコピーし、gziptarで展開して送信待ちのステージングアーティファクトも検査した
  • 各ファイルには出所を識別できる固有マーカーを入れ、秘密ファイルには次のようなダミー値を使った
    • API_KEY=CANARY7F3A9-SECRET-should-not-leave
    • DB_PASSWORD=CANARY7F3A9-DBPASS

チャネルA:読み取ったファイルと.envのモデル要求送信

  • Grokが読み取ったファイル内容は、POST cli-chat-proxy.grok.com/v1/responsesモデルターン本文にシリアライズされていた
    • キャプチャした48,070バイトの要求には"model":"grok-4.5"とメッセージ配列が含まれていた
    • .envAPI_KEYDB_PASSWORDのcanaryが改行まで含めて原文そのままで見つかった
    • ソース、ロジック、README、ネストされたJavaScriptファイルと2つの秘密値を含む6個のマーカーを要求本文から復元できた
  • 同じ内容はsession_stateアーカイブにも入り、POST /v1/storageでアップロードされ、その保存要求はHTTP 200で受理された
    • 圧縮アーカイブを展開して調べると、2つの秘密値と他のファイルマーカーがすべて見つかった
    • 秘密値はモデルが一時的に処理するだけでなく、保存用アーカイブにも記録されていた
  • Reply exactly OK, do not read any filesという統制プロンプトでは、開いていないuntouched_secret.txtのマーカーは/v1/responses本文に現れなかった
    • これはモデル要求チャネルがエージェントが実際に読んだファイルを中心に構成されている範囲だけを示す
    • 別のリポジトリ全体スナップショットチャネルには未読ファイルも含まれるため、この統制結果はリポジトリ全体アップロードを否定しない
  • 秘密値は.envまたはsecrets.envにあり、Gitで追跡されるファイルだった
    • .gitignoreに含まれるファイルもアップロードされるかどうかは別途試していない
    • canaryは実際の高エントロピートークン形式ではないため、sk-…のような特定形式向けの別個のマスキング機構がまったくないとまでは立証しない
    • 確認できた範囲は、テストした.envの内容がマスキングされずに送信されたという点

チャネルB:未読ファイルまで含むリポジトリ全体のアップロード

  • /v1/storageは、モデルが読んだファイルを送る/v1/responsesとは別にワークスペース全体のスナップショットをアップロードしていた
  • 実際のcereblab_apiリポジトリでReply with exactly: OK. Do not read or open any files.と指示したうえで実行した
    • GrokはPOST /v1/storageで152,102バイトのgit bundleを送信し、サーバーはHTTP 200を返した
    • キャプチャしたuploaded_repo.bundlegit cloneすると、開かないよう指定したsrc/_probe/never_read_canary.txtが復元できた
    • ファイル内のCANARY-XR47P2-NEVERREAD-UNIQUEマーカーも原文そのまま残っていた
    • bundleには4件のコミット、47個のファイルと完全なGit履歴が含まれていた
  • 2つ目の独立リポジトリcereblab_authでも同じ結果が再現された
    • POST /v1/storageで31,743バイトのgit bundleがアップロードされ、HTTP 200を返した
    • 復元したリポジトリで、未読ファイルのCANARY-AUTH-4T8K2-NEVERREADマーカーがそのまま確認できた
  • 別の298ファイル規模のcereblab_api実行では、ステージングされたmanifestが未読ファイルまで列挙していた
    • src/_probe/never_read_canary.txtsrc/apns.ts, src/index.tsなどの実際のソースが一緒に記録されていた
    • metadata.jsonのファイルごとのfileIdgs://grok-code-session-traces/repo_changes_dedup/v2/supplemental/sha256_…形式だった
    • この実行ではクォータに阻まれてコンテンツblob送信までは完了しなかったが、別のgit bundle実験と12GB実験で実際のアップロードが確認された
  • バイナリにはafter_codebase.tar.gz, repo_state.upload, collecting workspace files, spawning background coordinatorといった文字列も含まれており、ワークスペース収集メカニズムと一致していた

12GBリポジトリで確認した複数GiBの送信

  • 圧縮されにくいランダムファイルでリポジトリサイズを増やしながらアップロード挙動を観察した
    • 64MBでは約48MBの単一POST /v1/storageがHTTP 200を返したが、ログは保存できなかった
    • 約600MBでは約7.5MBチャンクが数十個すべてHTTP 200を返したが、ログは残っていない
    • 約3GBではmultipart初期化後にstorage.googleapis.comへ50MB単位のPUTが観察されたが、直接PUTのログは保存できなかった
    • 約12GBでは約75MBチャンクを/v1/storageへ継続送信し、5.10GiB時点でキャプチャを中断した
  • 保存されたwire_12gb.logには/v1/storage*のHTTP 200応答が合計83件ある
    • コンテンツアップロードPOST /v1/storageが82件
    • このうち約75MBチャンクが73件
    • 73件のチャンク合計は5,476,083,317B、すなわち5.10GiBまたは5.48GB
    • 小さいPOST 9件と/v1/storage/batch_existsの重複確認1件も含まれる
    • /v1/storage*要求の総バイト数は5,476,228,005Bで、失敗した保存要求はなかった
  • キャプチャはアップロード継続中に中断したため、12GB全体のアップロード完了を立証するものではない
    • 最後の記録も約75MBチャンクに対するHTTP 200だった
    • 立証できる範囲は、5.10GiB以上が失敗なく送信され、中断時点でも増え続けていたということ
  • 同じセッションの2チャネル間には大きな容量差があった
    • /v1/responsesは5件の要求を合計して196,705B、約192KBで、最大の要求でも60,394Bだった
    • /v1/storageは5.10GiBだった
    • 27,800倍の差が生じ、モデル要求に含まれていない大量のリポジトリデータが別の保存チャネルへ移動していた
  • モデルのクォータエラーと保存アップロードは独立して発生していた
    • /v1/responsesではHTTP 402が1回、429が3回発生した
    • セッションbookkeeping要求では無関係な404が1回発生した
    • 最初の429の後も/v1/storageのHTTP 200が76回続いた
    • 保存要求82件はすべて成功し、テスト範囲では保存容量制限エラーは発生しなかった
  • この結果はローカルupload_queueが空になる現象には依存しない
    • キューはアップロード成功時にも破棄時にも空になる可能性があるため、証拠として使っていない
    • 根拠は、要求本文が実際にネットワークへ送出されHTTP 200を受けたキャプチャと、アップロードされたgit bundleからファイルを復元した結果である

保存先とテレメトリ

  • 保存先はAWS S3ではなく、Google Cloud Storageの**grok-code-session-tracesバケット**と確認された
    • バイナリにgrok-code-session-traces, storage.googleapis.com, Uploading bytes to GCS via proxyが含まれていた
    • 保存されたmetadata.jsonにはファイルの宛先がgs://grok-code-session-traces/…として記録されていた
    • 約3GBの実験では当該GCSホストへの直接multipart PUTも観察したが、ログは保存できなかった
    • バイナリにaws-sdk-s3が含まれていても、テストで確認できた宛先はGCSだった
  • サードパーティおよび自社のテレメトリ要求も確認された
    • Mixpanelのapi.mixpanel.com/track/engage
    • grok.com/_data/v1/events
    • これらの要求はいずれもHTTP 200を返した
  • 確認したCLIインストールスクリプトとquickstart資料では、repo_state, session_state, ~/.grok/upload_queue, grok-code-session-tracesへのアップロードは見つからなかった
    • すべてのxAI文書とヘルプを調査したわけではないため、どこにも文書化されていないと断定はできない
    • 確認可能な範囲は、CLI自身の設定資料では明示されていなかったということ
  • ~/.grok/upload_queueは1ターンで約3GBのスナップショットをステージングでき、高負荷時には数十GBまで増えてディスクを使い切る可能性があった
    • これはアップロードのプライバシー問題とは別の信頼性の問題である

「Improve the model」設定とポリシー範囲

  • クラウド型コーディングエージェントが作業に必要なコード文脈をサーバーへ送ること自体は必要な動作である
  • テストで確認された挙動は次の3点に分けられる
    • .envのような秘密ファイルをマスキングなしで送信する
    • その内容を明示されたGCSバケットに保存する
    • リポジトリ全体のアップロードが、確認したCLI設定資料に明示されないままデフォルトで有効になっている
  • xAIの消費者向けポリシーは、モデル改善のためのデータ利用とopt-outを広く扱っており、Private Chatは自動opt-outで、opt-outは遡及適用されない
    • 関連文書はxAI Privacy PolicyConsumer ToS
    • こうした一般的な学習ポリシーは、特定のrepo_stateおよびGCSアップロードパイプラインを文書化することと同義ではない
  • 「Improve the model」をオフにしてもアップロードは止まらない

    • 設定をオフにしてもリポジトリ全体がgit bundleとして/v1/storageへアップロードされ、HTTP 200を返した
    • git cloneで未読ファイルとGit履歴を復元できた
    • CLIが受け取った/v1/settingsには"trace_upload_enabled": true, "upload_enabled": true, "session_registry_enabled": trueが維持されていた
    • "max_upload_file_bytes": 1073741824として、ファイルごとの1GiB制限も返されていた
    • テスト結果では、opt-outは学習への利用可否を制御するが、リポジトリがコンピュータを離れてアップロード・保存される動作自体は遮断しなかった

立証していない点と証拠の限界

  • ネットワークキャプチャだけでは、xAIがデータをモデル学習に使用する事実を立証できない
    • 確認できた範囲は、送信、HTTP 200による受理、保存用アーカイブとGCS宛先である
  • 3GB実行で観察したstorage.googleapis.com/grok-code-session-tracesへの直接PUTログは上書きされて保存されなかった
    • 複数GiBアップロードの根拠は、保存された12GB実行の/v1/storageログと、バケットを明示したバイナリおよびmetadataである
  • サイズ別試験のうち64MB、600MB、3GBのログは残っておらず、12GBログのみ保存されている
  • 12GB実行は約5.10GiBで中断したため、12GB全体が最後までアップロードされると断定はできない
  • すべてのアカウント種別と構成の組み合わせを試したわけではない
    • 無料プランで複数GiBのアップロードが成功した
    • SuperGrokでは「Improve the model」をオフにしてもgit bundleアップロードが成功した
    • テストではアップロードをオフにする設定は見つからなかったが、どの環境でも絶対に無効化できないと断定はしない
  • 当初はPID単位のnettop結果を根拠に大容量blobがアップロードされていないと誤判断していたが、これは撤回する
    • 別個のアップロード調整プロセスと、GoogleのIPへ直接向かう事前署名付きPUTは、APIホストや単一PID基準の計測から漏れる可能性があった
    • その後のプロキシによるワイヤキャプチャが初期判断に置き換わった
  • 結果はgrok 0.2.93、macOS Apple Silicon、2026年7月の環境に限られ、xAIが後に挙動を変更する可能性がある

保存された主要証拠

  • secrets_responses_body.bin.env原文が/v1/responses本文に含まれていたことを示す
  • secrets_session_state.tar.gz:同じ秘密値が/v1/storage用アーカイブに入っていたことを示す
  • wire_12gb.log:5.10GiBの保存アップロード、83件の/v1/storage* HTTP 200、保存失敗0件と、2チャネル間の約27,800倍の容量差を記録
  • model_limit.txt:モデル要求で発生した402が1回、429が3回であることを記録
  • crate_strings.txtxai-data-collector, grok-code-session-traces, storage.googleapis.comの文字列を保存
  • uploaded_repo.bundle:アップロードされたgit bundleから未読ファイルと完全なGit履歴を復元した、最初のリポジトリ証拠
  • uploaded_repo_auth.bundle:2つ目の独立リポジトリで同じ結果を再現した証拠
  • staged_base_tree_manifest.json:未読ファイルがリポジトリスナップショットmanifestに列挙されていたことを示す
  • staged_metadata.json:ファイルの宛先がgs://grok-code-session-traces/…であることを示す
  • gcs_puts.txtは直接GCS PUTを保存できなかったため空のプレースホルダーであり、そのPUTの保存証拠としては使えない

1件のコメント

 
GN⁺ 4 시간 전
Hacker Newsの意見
  • コーディングツールとLLMプロバイダーは常に分離し、bubblewrapサンドボックスでコーディングツールの権限を制限している
    ツールは作業プロジェクトディレクトリだけを読めて、.gitは読み取り専用、機密ディレクトリは空のディレクトリとしてマウントする
    ネットワーク名前空間も分離し、UnixソケットのHTTPプロキシ経由でのみインターネットにアクセスさせ、特定のLLMプロバイダーホストだけを許可し、ツール自体のホストは遮断する
    たとえばCrushには*.openrouter.aiへのアクセスを許可するが、LLM一覧の自動更新に使われる*.charm.landはブロックする。おかげで**yoloモード**ですべての作業を任せやすくなる

    • bubblewrapでは、Docker Hubのdebian:unstableのようなrootfsを取得し、別フォルダに完全なディストリビューション環境として構成するのがよい
      その中にAIエージェントをインストールし、ディストリビューションrootfsは読み取り専用、カスタムの/home/userは読み書き可に設定してbwrapを実行するスクリプトを作ればよい。指定したディレクトリ外の重要ファイルは見えず、複数のエージェントを互いに見えないように実行することもできる
      さらに強化するなら、内部でgVisorのrunsc ... do ...を呼ぶか、muvmのような仮想マシンモニタを使える。bwrapは環境構成を担当させ、別のサンドボックスツールで封じる方式なので信頼しやすい
      設定が正しければ、bwrapだけでもほとんどの攻撃者を防ぐには十分で、権限昇格には事実上Linuxカーネルのゼロデイが必要になる可能性が高い
    • これを実装する際にどんな方法を使っているのか気になる
    • こうした追加のセキュリティ強化が単なる安心材料にとどまるのか、実際に危険な動作を防いだことがあるのか気になる
      制約で防がなければならないほど愚かな振る舞いをするモデルなら、そもそも使う価値がないと思う。自分も環境を強化している最中で、慣行そのものを批判したいわけではない
  • claude-code、Codex、grok-buildのような独占的なネイティブコーディングエージェントランナーは、次のアップデートでどんな非公開機能が追加されるかわからず、プライバシーの面で危険だ
    opencodeでAPI経由でモデルを使うほうがはるかに安全だが、ネイティブランナーほどの性能を出しにくいというトレードオフがある

    • 使用量が十分なら、サーバー側のツール呼び出しだけでもコードベース全体を再構築でき、この過程は完全には検出しにくい
      Grokのやり方がより露骨なだけで、opencodeも実質的なセキュリティ境界を作れておらず、チートスを南京錠代わりに使うミームに近い
    • Codexはオープンソース
    • 自動更新自体も大きな問題だ
      Windows XP SP1のリモートコード実行脆弱性のようなものを即座に修正しないのも危険だが、この数十年でアップデートしなかったために起きたであろう被害より、自動更新によって起きた被害のほうを多く見てきた
    • 独自エージェントは使っているが、そのせいで会社のアカウントが停止されるリスクは負えない
  • 「エージェントが読んだファイルと無関係に、追跡中のすべてのファイル内容とGit履歴を含むリポジトリ全体をアップロードする」というのは非常に衝撃的だ
    Elonが追いつくためにこういうことをするかもしれないとはある程度予想していたが、深刻に懸念している。価格競争力があり、grok-4.5の性能も十分高いが、まさにこういう理由で選ばなかった

    • 明白なデータ流出であり、違法であるべきだ
    • Microsoftとの協力関係のため、OpenAIもすべてのGitHubリポジトリにアクセスできるのか気になる
    • 結局は底辺への競争
    • どのデータを共有する必要があるのかに関する情報が見つからず、無料トライアルすらためらった
    • こうしたCLIは、常にアクセス可能なディレクトリを制限するサンドボックス内で実行する
      CLIが誤ってSSHキーや他の機密情報を持ち出すかもしれず、プログラマーは実際こうしたミスをよく犯す。「アクセス可能なすべてのファイルをアップロード」が意図的なのかミスなのかに、安全を委ねたくない
  • 最初の項目である「リポジトリ内の秘密情報ファイルをモデルが読んだ」は、事実上意図された動作
    LLMはファイルを読む前に、その中に秘密情報があるかどうか判断できない。平文の秘密情報が入ったファイルへのLLMアクセス権を与えておいて、読んだと驚く側に根本的な問題がある
    ただし、リポジトリ全体を自動でアップロードするのはばかげている。数GB規模のリポジトリなら回線によっては非常に長くかかるし、すべてのデータを集める別の目的がない限り、たいてい無意味に見える

  • エージェントを動かしている現在のワークスペースは、少なくともエージェントが自由に扱えるものだと常に想定してきたので、予想どおりの動作に見える
    ほとんどのエージェントは最初のプロンプトでコードとその中の秘密情報まで読む。サーバー側でこれを活用してプロンプトの往復時間とツール呼び出しを減らせるなら、むしろユーザーに利益があるのではないかと思う

    • ファイルを読み、応答を返すときには通常のメッセージAPIを使う
      ところがここでは、プロジェクトフォルダ全体をGCPストレージバケットへ持ち出す別エンドポイントが見つかった。大規模分散システムを設計したことがある人なら、訓練データをかき集めるための構造だとわかるはずだ
    • Cursorはローカルで一種のインデックス作業をしていると理解している
      すべてのファイルをアップロードしなくても、検索で関連部分だけを見つけてモデルが使えるよう送信できる
  • 概要を人間が書いていればよかったが、内容自体は不安になる

    • アップロードされる内容を示すコードブロック数個と2〜3段落で十分だったはずの記事だ
      AIが書いた報告は読むのがあまりにつらく、10秒ほど流し見しただけで興味を失った
    • 少なくとも人間がLLMと何度かやり取りして、文体を改善することはできたはずだ
  • 盗んだ内容が「すべてのビジネスを自動化」するMacrohardプロジェクトや「everything app」に入るのか気になる
    何でも自分で作る必要はなく、盗めばいいという発想に見える

    • ユーザーがこうした特権のために金まで払うのが極めつけだ
      倫理観のないままこういう会社を運営するなら、詐取の規模が明るみに出て規制で止められる前に、できるだけ多く盗もうとするはずだ。実際にそうしていると言っているわけではないが、経済的インセンティブはまさにその方向に揃っている
  • AIエージェントは、実行プログラムが起動されたディレクトリ内のファイルを読めると考えるべき
    ほとんどは最初のプロンプトでコードとその中の秘密情報まで読み、.envはローカル環境用なので実際の秘密情報を入れてはいけない。AIエージェントの指示は信頼できないため、本物の秘密情報とは隔離すべき
    この前提を受け入れるなら、毎回コードをコンテキストとして送るよりサーバーに置いておくほうがよいかもしれない

    • LLMの動作上、結局コードはコンテキストを通じて再送される必要がある
      このように別途アップロードする理由は、Muskが次のモデルのためにプロジェクト構成、人気ライブラリ、CIワークフローのようなクリーンな学習データを確保したいだけだと見ている
    • 一度アップロードしても推論過程には依然として入ってきており、節約できるのはHTTPトラフィックが少しだけという程度
    • 話の核心はそれほど大きくない。Grokが他のプロバイダーよりコンテキスト構成で10%ほど積極的なだけか、単にこの方式のほうが早くリリースできた可能性が高い
      どのプロバイダーにも、結果改善に役立つなら同じことをする能力と動機がある
      本当の違いは、.envのような秘密情報ファイルをマスクせずに送信し、一時的に処理するだけでなく名前付きのGCSバケットに保存し、CLI設定ドキュメントでアップロード方式を知らせないままデフォルトで有効化していたこと
      アクセス可能なパスに暗号化されていない.envを置くべきではない。Grokが秘密情報を識別して無視してくれるほうが望ましいが、ユーザーがそのような動作に依存すべきではない
  • 「Improve the model」設定をオンにしていてもオフにしていても、リポジトリ全体が同じようにアップロードされる点は非常に深刻
    ほとんどのAI企業も、データ収集に同意すれば自社の実行環境で似たことをするだろうが、明示的にオフにしたのにアップロードするのは悪質

  • コードベース全体をアップロードすると、モデルは「考えている」間、クライアントに実際のツール呼び出しを要求しなくてもコードを見られる
    クライアントへ再要求することの欠点が何なのか不明なので、それほど強い理由ではないが、考えうる最善の口実ではある

    • 実際の目的は、営業秘密、アプリ設計、社内業務知識を盗む、あるいはコード・アプリ・ツール・手順を複製することにより近く見える
      もともと非公開だったコードが、今では彼らのコードになる
    • コンピューターがオフラインでも、どこかのコンテナ経由でスマートフォンからリモート操作し、後でローカル開発に戻ってGCPバケットの変更を同期する用途かもしれない
      かなり便利ではあるが、Elonにリポジトリ全体を渡すほどの価値はない。拒否できない形にし、しかもまったく公開していなかったという事実は、このデータを預けるべきではないという判断をさらに強める