世界を動かす技術を、日本語で。

Nxが侵害される:マルウェアがClaudeコードCLIを使用してファイルシステムを探索する

2025年8月27日原文(semgrep.dev)

概要

  • nx ビルドシステムの一部バージョンに マルウェア混入 が発覚
  • s1ngularity-repository というリポジトリが GitHubアカウントに自動生成
  • マルウェアは ウォレットやAPIキーなどの機密情報を窃取
  • Claude Code CLIやGemini CLI の存在確認後、LLMプロンプト経由で情報収集
  • 影響範囲、対処法、今後の対応策について 公式アドバイザリ あり

nxビルドシステムにおけるマルウェア混入事件

  • 2025年8月26日nx の一部バージョンに マルウェア が仕込まれた事案が発生
  • s1ngularity-repository という名前で GitHubリポジトリ が自動で作成される現象
  • マルウェアの主な目的 は、 ウォレット情報やAPIキー (.npmrc、環境変数など)の窃取
  • 窃取した情報は results.b64 ファイルとしてリポジトリに格納
  • Claude Code CLIやGemini CLI が検出されると、LLMプロンプトを通じてさらなる情報収集を実施

影響を受けるバージョン

  • nx v21.5.0 ~ v21.8.0
  • nx v20.6.0 ~ v20.12.0
    • これらのバージョンは npmから既に削除済み

具体的な被害と挙動

  • GitHub CLI を用いて s1ngularity-repository を自動作成
  • 環境変数やウォレットファイル を探索・収集し、 base64で2重エンコード してアップロード
  • LLMプロンプト を使い、 Linux/macOS の特定パスを再帰的にスキャンし、 ウォレット関連ファイル を収集
  • .bashrc等のシェルファイルshutdownディレクティブ を追加し、不正な動作を隠蔽

発覚から対応までのタイムライン

  • 2025-08-26 18:00 PDT :不正なnxバージョン公開(v20.9.0 - v20.12.0、v21.5.0 - v21.8.0)
  • 2025-08-26 20:30 PDT :最初の被害報告
  • 2025-08-26 22:45 PDT :npmから該当バージョン削除
  • 2025-08-26 23:45 PDT :nrwlが不正npmアカウント削除
  • 2025-08-27 01:00 PDT :@nx/配下の追加パッケージも影響範囲に追加

影響確認・対処方法

  • GitHub組織s1ngularity-repository が存在しないか確認
  • semgrep による脆弱バージョン検出
    • semgrep --config r/oqUk5lJ/semgrep.ssc-mal-resp-2025-08-nx-build-compromised
    • またはnx --versionやlockfileでバージョン確認
  • 対処手順
    • nxを安全な最新バージョン(21.4.1)へアップデート
    • s1ngularity-repositoryコピー後、削除
    • 漏洩した可能性のある全てのシークレットをローテーション
      • GitHub、npm、SSHキー、環境変数等
    • .bashrc等のshutdownディレクティブを削除

マルウェアの技術的特徴

  • post-installフックtelemetry.js を実行
  • プロセス環境変数ウォレットファイル をダンプ
  • GitHub CLI を利用し、 認証トークン でリポジトリ作成
  • Claude Code CLIやGemini CLI があれば、 LLMプロンプト 経由で情報収集
  • 収集結果を2重base64エンコードし、GitHubリポジトリへアップロード
  • LLM活用 により、 マルウェア本体の検出を困難化

NXとは

  • NXモノレポ に特化した 大規模プロジェクト向けビルドシステム
  • 2.5百万人以上の開発者 が日常的に利用
  • VSCode Cursor拡張等 で自動的に最新版へアップデートされる場合も多い

関連情報・参考リンク

今後の対応と注意点

  • 公式アドバイザリや最新情報を随時確認
  • 組織内リポジトリの監視を継続
  • npm等のサプライチェーン攻撃への警戒強化
  • 秘密情報管理の徹底と定期的なローテーション
  • LLM等の新たな攻撃手法への理解と対策

Hackerたちの意見

正直言って、今はほとんどのコーディングをVMでやってる。これらのセキュリティプロファイルが許容できるとは思えない。マルウェアのベクターとしてのエージェントからの潜在的な脅威レベルは本当に桁外れだよ。今、私たちは、侵入したときに何を探しているのかもわからずに、1,000ドル以上の身代金データや暗号キー、パスワード、脅迫材料、財務記録のチャンスをスキャンできる時代に突入している。

今はほとんどのコーディングをVMでやってる もしかしたらQubes OSに興味があるかも。すべてをVMでやって、使いやすいUXがあるよ。私のメインの環境で、めちゃくちゃおすすめ。

似たような感じだけど、ホストマシンとはソースコードのディレクトリ以外は何も共有しないpodmanコンテナの中で動かすよ。

新しい依存関係を追加する際には、もっと慎重に考えるべきだよ。今年は供給チェーン攻撃が多すぎる。今週、Goプロジェクトに8つの統計カウンター付きのプログレスバーを追加する必要があったんだけど、ライブラリを見たら、どれも3,000行以上のコードだった。LLMにシンプルなプログレスレポートトラッキングUIを作ってもらったら、150行未満で済んだ。期待通りに動くし、依存関係もいらない。すごくシンプルで、誰でもコードが理解できる。ターミナルの出力をクリアして、毎秒再描画するだけ。スレッドセーフでもあるし、統合してコードをレビューするのに25分かかった。複雑な統計カウンターが必要ないなら、シンプルなプログレスバーは30行くらいで書ける。これから新しい依存関係を考えるときは、これが私のやり方になりそう。すべてのパッケージの更新を監査するリソースはないからね。

これらの依存関係がなければ、AIがあなたのコードを書くためのトレーニングデータは存在しない。

外部ライブラリを導入する価値の一部は、彼らが改善したら自動的にその恩恵を受けられるってことだったんだよね。でも今は、彼らが「改善」したら自動的にその影響を受けるっていう脅威がある。left-padの問題は、みんなにとって大きな警鐘だったはずなのに、結局のところ「10行のコードのために依存関係を全部引っ張ってくるなんて、あいつらバカだな。俺は100行のコードのために依存関係を引っ張ってくるから賢いんだ」っていう教訓を得たみたい。

新しい依存関係を追加する時は、みんなもっと考えるべきだよ。今年はサプライチェーン攻撃が本当に多かったからさ。「言語パッケージマネージャー」が流行り始めた時は、すごく不安だった。俺はシステムプログラミングの世界で働いてるから、過去10年間はpipやnpmみたいなものをちょっと疑いの目で見てたんだ。でもRustのプロジェクトをやってみて、Cargoを使って設定ファイルの1行で完全にレビューされてない依存関係を何十個も簡単に引っ張ってこれるのを見た時、これはヤバいことになるって思ったよ。案の定、これは悪い方向だし、今すぐ戻るべきだね。(でも戻らないだろうけど。コンピュータセキュリティなんて存在しないから。)

基本的にgit cloneをするパッケージマネージャーが欲しいし、「依存関係は極力少なくして、ソースコードをリポジトリにコミットして、アップデートの時に変更をレビューする」って文化があればいいなと思ってる。それがあれば、現代のパッケージ管理の混乱が大きく改善されると思う。

正直、あの進捗トラッカーが大嫌い。emacsシェルを壊すから(お前ら、expoとeasを見てるぞ)。シンプルなカウンターを表示すればいいのに、例えば「..10%..20%..30%」とか。「Uploading…」でもいいじゃん。ターミナルコードはTUIかインタラクティブ専用で使うべきだよ。

私のチームではNXをたくさん使ってるけど、全然影響を受けてないよ。大手保険会社で、10以上のスタンドアロンのビジネスアプリと25以上の個別ライブラリを同じモノレポでNXが管理してる。こういう複雑なセットアップのために他のモノレポツール(lerna、rushjs、yarn workspaces)を試したこともあるけど、どれも近づくことすらできなかった。lernaはNXにほぼ引き継がれてるし、rushjsはメンテされてない。もし、日々の開発者が何十人も関わるFEモノレポの複雑さを適切に管理する方法があれば、代替案を投稿してほしいな。最近のセキュリティインシデントもあって、多くの人が探してるから。

正直、Goで機能を実装する時は、パッケージを使うよりも自分で書いた方が簡単でコードも少ないと思う。TypeScriptと比べると、パッケージを使うためのコードが必要になるから、ゴーランでやったことと比べて常に多くの行数になるんだよね。

それはライブラリとカスタム構築の違いだね。ライブラリは定義上、ある程度一般的で適応可能、設定可能であるべきなんだ。それにはたくさんのコードが必要だよ。

Hacker Newsで議論の続きを見る