TL; DR
2025年9月14日、研究者たちは シャイ・ハルード内部に隠れた自己複製するワーム npmパッケージルーチン的な依存関係の更新を本格的な サプライチェーン攻撃最初に発見されたのは @ctrl/tinycolor Daniel dos Santos Pereira によるパッケージ Shai-Hulud は秘密情報を収集し、GitHub リポジトリとワークフローを通じて外部に漏洩させ、盗まれた認証情報を使用してレジストリ全体に自身を再公開します。数日のうちに感染したパッケージの数は数十から数百に急増し、 シャイフルード これは単なるトロイの木馬ではなく、npmエコシステム全体に自動的に拡散するように設計されたワームです。
影響: 公開されているnpmパッケージをインストールする開発者やCIランナーは、誰でもリスクにさらされます。
即時アクション: 既知のバージョンをブロックし、ロックファイルのみのインストールに切り替え、npmおよびGitHubトークンをローテーションし、ワークフローを監査し、侵害の兆候(IoC)を監視します。
何が起きましたか?
その npmパッケージにおけるShai-Huludサプライチェーン攻撃 これは近年で最も破壊的な事件の1つです。孤立したトロイの木馬とは異なり、このワームは 認証情報の窃盗、自動的なデータ流出、および自己複製その結果、感染から回復するまでの期間は数週間からわずか数時間に短縮された。
DevOpsチームにとって、教訓は明確だ。すべてのインストールがコードを実行できるのであれば、すべての依存関係の更新は潜在的な脆弱性となる。
考えられる初期攻撃経路と標的となる認証情報
初期分析 攻撃はおそらく 盗まれた認証情報例えば、npmを偽装したフィッシングキャンペーンなど。 login または、MFAプロンプトによって開発者トークンが盗まれた可能性があります。攻撃者が最初の足がかりを得ると、ワームはnpmパッケージに自身を埋め込むことで拡散し、さらに以下のものから機密情報を盗み出しました。
- npm設定ファイル ような
.npmrc多くの場合、公開トークンが含まれています。 - 環境変数 GitHub PAT を使用した構成と CI/CD 秘密。
- クラウドメタデータエンドポイント (AWS、GCP、Azure) は、横方向の移動のための短期的な認証情報を提供する。
そのため、認証情報の窃盗が攻撃の足がかりとなった。有効なnpmトークンとGitHubシークレットがあれば、Shai-Huludは人手を介さずに複数のパッケージやリポジトリに自己複製することができた。
シャイ・フルードサプライチェーン攻撃が経営幹部に及ぼす影響
Shai-Huludは現在も活動しています。このワームは影響のタイムラインを加速させます。かつてトロイの木馬で数週間かかっていたことが、今では数時間で起こります。その結果、 感染拡大はより速く、封じ込めるのがより困難になる。 それは以下の方法で前進します。
- npmの公開トークンとGitHubのシークレットを盗む。
- 他のnpmパッケージに自身を再公開する。
- 永続化のために悪意のあるGitHub Actionsワークフローを追加する。
影響を受ける人:
公開されているnpmパッケージをインストールするチームはすべて脆弱性にさらされます。さらに、キャッシュされたnpmトークンやGitHubトークンを使用している開発者は、高いリスクに直面します。広範囲のシークレットを使用するCIランナーも脆弱です。
ビジネスリスク
ビジネスへの影響は急速に拡大します。盗まれたトークンは、アカウント乗っ取り、パッケージハイジャック、さらにはクラウドの不正利用につながる可能性があります。さらに、GitHubワークフローにおける永続性は、クリーンアップをより困難にします。したがってチームはシャイ・フルード事件を解決済みの事件としてではなく、現在も進行中の事件として扱わなければならない。
npmパッケージにおけるShai-Huludサプライチェーン攻撃の仕組み
攻撃者の目的と動機
このキャンペーンは、以下の3つの点を最適化します。
- 最初の目的は 認証情報を大規模に盗む 開発者のノートパソコンやCIランナーから情報が盗まれています。これには、npmの公開トークン、GitHubトークン、クラウド認証情報などが含まれます。実際、複数の分析で、TruffleHogの実行やクラウドメタデータエンドポイントへのクエリなど、組織的なシークレット情報の収集が確認されています。
- 2つ目の目的は 自動的に伝播する 侵害されたメンテナーの公開権を悪用することで、感染が拡大する。その結果、新たな感染バージョンが人手を介さずに他のパッケージに出現するため、一つの足がかりが瞬く間に多くの感染源へと広がっていく。
- 3つ目の目的は 持続し、確実に排出する GitHubインフラストラクチャを介して、攻撃者は「Shai-Hulud」という名前の公開リポジトリを作成し、二重のbase64エンコードを施します。 データ.jsonさらに、彼らはシリアル化するワークフローを植え付けます。 ${{ toJSON(secrets) }} そしてそれを静的ウェブフックに投稿します。
期待されるメリットには、レジストリとソースコードへの長期アクセス、クラウドアカウントへの迅速な横方向移動、サプライチェーンをさらに武器化するオプションなどが含まれます。公開レポートによると、プライベートリポジトリがパブリックに切り替わり、 「-移住」 データ露出と勢いを高める接尾辞
Shai-Huludペイロードの内部: バンドル.js npmパッケージ
Shai-Hulud は 大規模で、Webpackでバンドルされ、高度にミニファイされています。 JavaScriptファイル (バンドル.js(約3~3.7MB) それは インストール後 フックイン package.json。 その結果, インストールのたびにペイロードが自動的に実行されます。この設計では、識別子を隠蔽し、制御フローを圧縮し、すべてのロジックをインストール時に実行される単一のアーティファクトに集約しています。アナリストは、Webpackによるバンドル、異常なファイルサイズ、およびインストール時の実行を一貫して確認しています。
サンプルに見られる難読化および解析妨害の特徴:
- ミニファイされたモジュールグラフ 数値モジュールID、疎なコメント、フラット化された制御フローを備えています。さらに, この構造では、手動によるレビューが非常に困難になる。
- 文字列の非表示 base64レイヤーと構築ヘルパーを介して。例えば, 繰り返し行われるbase64エンコードとデコードは、通常、データ漏洩処理の周辺で見られます。
- 動的ディスパッチ 評価する-スタイルパターンと生成された関数本体により、コードが実行時に動作を変更できるようになります。
- OSフィルタリング 特にCIランナーや開発者用ノートパソコンでは、LinuxとmacOSでの実行を優先する。
機能的な観点から見ると、このバンドルはモジュール式である。 解説記事では、OS検出、ファイルシステムおよびGitシークレットのスキャン、クラウドSDKへのアクセス、GitHub API操作、そしてメンテナーが所有する他のパッケージを編集する伝播エンジンなどのモジュールについて説明しています。実際、StepSecurityとReversingLabsはどちらも、悪意のあるフックを使ってパッケージを自動的に更新する機能を強調しています。
Shai-Huludにおけるインストール時の実行:npmパッケージがワームをトリガーする方法
攻撃は、 postinstall はノードを実行します バンドル.js. この時点で、スクリプトはメモリ内で作業状態を初期化および展開し、ワームの完全な動作のための準備を整えます。
発見と収穫
- このペイロードはprocess.envをダンプし、ローカルファイルをスキャンしてエントロピーの高い秘密情報とトークンプレフィックスを検出します。さらに、TruffleHogを実行することでカバレッジを拡張します。
- クラウドメタデータエンドポイントにクエリを実行して、有効期限の短い認証情報を収集します。 例えば、 への呼び出し
169.254.169.254AWS 上またはmetadata.google.internalGCPは感染した宿主によく出現する。 - その結果、 見つかった認証情報は、新しいnpmパッケージの公開やGitHubワークフローのプッシュに即座に使用可能になります。
exfiltration
- ワームは新しいGitHubリポジトリを作成します。 シャイ・ハルード そして、二重のbase64エンコードされた
data.jsonプラットフォームの詳細、環境ダンプ、秘密情報などが含まれています。ご覧のとおり、防御側がどこを探せばよいかを知っていれば、このようなノイズの多い動作は簡単に発見できます。 - また、GitHub Actionsワークフローを、多くの場合、特定の名前のブランチに植え付けます。 シャイ・フルドシリアル化する
${{ toJSON(secrets) }}そして、データを静的なWebhookに送信します。さらに、このワークフローは誰かが明示的に削除するまで継続されます。
伝播
- 検出されたnpmトークンに基づいて、ペイロードは侵害されたメンテナーが所有するすべてのパッケージを列挙します。次に、各tarballを取得し、bundle.jsとpostinstallエントリを挿入して、パッケージを再公開します。
- その結果、感染した荷物が数時間のうちに数十個も出現し、生態系全体における影響範囲が拡大する可能性がある。
粘り強さと露出
このワームは悪意のあるワークフローを維持し、いくつかのケースではプライベートリポジトリをパブリックリポジトリに切り替えます。 「-移住」 接尾辞。これらすべてにより、攻撃者は足がかりを維持し、データ漏洩を最大化することができます。
鍵検出に関するメモ
この珍しい使い方 ${{ toJSON(secrets) }} Actionsワークフローでは、このようなケースは稀です。 したがって、 チームは、狩猟中にこれを高信号指標として扱うべきである。
探し出すべき、サニタイズされたワークフローパターン
この珍しい使い方 〜へ JSON(秘密情報) この事件において、「行動」は高シグナル指標である。
高レベルの伝播擬似コード(安全で分かりやすい)
アナリストたちはこのループが大規模に発生していることを確認しており、それが感染した荷物の数が数十個から数百個へと急速に増加した理由を説明している。
なぜこれがパッケージエコシステム内のワームなのか
ワームは、各段階でオペレーターによる手動操作を必要とせずに自発的に拡散するマルウェアです。オペレーティングシステムでは、ワームは通常、ネットワークの脆弱性を悪用してマシン間を移動します。対照的に、Shai-Huludはnpmレジストリ内で動作します。その効率的な経路は、 資格情報の再利用.
このワームは、盗まれたnpmの公開トークンを悪用します。有効な認証情報を取得するとすぐに、同じメンテナーが所有する他のパッケージに感染したバージョンを再公開します。その後、何も知らない開発者やCIランナーによってそれらのパッケージがインストールされ、このサイクルが繰り返されます。
このため、セキュリティアナリストは、 暗読シャイ・フルードを 自己複製するワーム 単なるトロイの木馬やタイポスクワッティングとは異なります。その違いは重要です。トロイの木馬は通常1つのホストを侵害しますが、ワームは自動的にエコシステム全体に影響を及ぼします。
「仕組み」早見表
シャイ・フルードのライフサイクルを要約すると、cisその主な手順の内訳:
- パッケージ インストール後 インストールされ、
bundle.js実行します。 - ペイロードは環境変数をダンプし、ファイルとgit履歴をスキャンし、 トリュフホッグクラウドメタデータサービスにクエリを実行する。その結果、発見された秘密情報は即座に有用となる。
- 流出は2つの方法で発生します。まず、パブリックリポジトリを作成し、 シャイ・ハルード ダブルベース64エンコード
data.json2つ目は、GitHub Actionsワークフローを投稿することで${{ toJSON(secrets) }}ウェブフックへ。 - 盗まれたnpmトークンを利用して、このワームは侵害されたメンテナーが所有する他のすべてのパッケージを同じ悪意のあるフックを使って再公開します。こうして感染は急速に拡大します。
- 最後に、攻撃者はより多くの秘密、拡散するためのより多くのパッケージを保有しており、 持続性 GitHubアカウントおよびリポジトリ内。
この種の攻撃を実際に回避する方法
Shai-Huludは警鐘です。トークンを盗んで自己再発行するワームは将来のリスクではなく、すでに現実のものとなっています。 npmパッケージのエコシステム 今日。このような事態を防ぐために サプライチェーン攻撃チームは、プログラム可能で自動化され、直接適用されるコントロールを必要としています。 CI/CD pipelineこれらは、すでに実装できる防御策と同じです。 ザイゲニ.
ゲートで悪質なアーティファクトを阻止する
npmパッケージとtarballは、開発者やCIジョブに届く前にスキャンする必要があります。 bundle.js ファイル、インストール後の不審な点 hooks、難読化マーカーはすべて早期の危険信号として機能します。さらに、クールオフ期間と固定バージョンを強制することで、 pipelinesは、検証されていない新しいリリースが自動的に消費されるのを防ぎます。
Harden CI/CD 初期設定で
Guardrails in CI/CD これらは不可欠です。新しいスクリプトやバイナリを導入するマージやインストールを拒否します。同時に、シークレットをシリアル化したり、外部への投稿を試みるワークフローをブロックします。チームはロックファイルのみのインストールも要求する必要があります(npm ci)全体にわたって pipeline依存関係セットが再現可能で安全であることを保証する。
トークンの爆発範囲を縮小する
秘密情報が単一障害点にならないようにする。コード、構成、 pipeline の出力 公開された認証情報トークンは、スコープを狭く設定し、有効期間を短くし、漏洩が検出された場合には自動的にローテーションさせるべきです。原則として、疑わしいインストール後処理を実行したホストで使用されたトークンは、すべて侵害されているものとして扱うべきです。
線虫の行動を早期に観察する
異常検出 が鍵となります。例えば、npm publish イベントの急増、理由もなく出現する新しいワークフロー、あるいは奇妙なエンコードされたファイルで満たされた新しいパブリックリポジトリなどは、ワーム活動の兆候である可能性があります。したがって、チームは迅速にアラートを発報し、これらの警告サインを示すメンテナーやランナーを隔離する必要があります。
ビルドを壊さずに迅速に修正
スピードと安全性は両立しなければならない。自動運転 pull requests 侵害された npm パッケージを検証済みのバージョンに置き換えることができます。さらに、 到達可能性 (NAIST) と 活用可能性 分析によって、アップグレードは最小限かつ安定したものに抑えられます。最後に、感染が確認されたら、影響を受けたCIランナーをクリーンなイメージから再構築し、攻撃のさらなる拡散を防ぎます。
侵入の痕跡(IoC)
シャイ・フルードを分析する際、チームは以下の点に注意する必要があります。 静的IoC ファイルと 行動IoC in pipelineこれらの信号が連携することで、感染を早期に発見し、寄生虫がさらに広がる前に対応することができます。
静的IoC
以下のSHA-256ダイジェストは観測されたものと一致します bundle.js サンプル:
- 46faab8ab153fae6e80e7cca38eab363075bb524edd79e42269217a083628f09
- 81d2a004a1bca6ef87a1caf7d0e0b355ad1764238e40ff6d1b1cb77ad4f595c3
- dc67467a39b70d1cd4c1f7f7a459b35058163592f4a9e8fb4dffcbba98ef210c
さらに、以下の繰り返し見られるパターンにも注意してください。
- A
bundle.jsパッケージのルートディレクトリで。 "postinstall": "node bundle.js"内部package.json.- リポジトリ名 シャイ・ハルード.
- GitHubワークフローを含む
${{ toJSON(secrets) }}.
行動IoC
ファイル署名以外にも、ワームの活動は挙動によって明らかになる。例えば:
- あるメンテナーから突然大量のnpm公開イベントが発生する。
- データを外部エンドポイントに送信する新しいワークフロー。
- CIランナーからトリガーされる送信POSTリクエスト。
- 最近作成された、エンコードされたブロブを含む公開リポジトリ。
クイックハント
結論:シャイ・フルードから学ぶ教訓
その シャイ・フルードのサプライチェーン攻撃 npmパッケージにおけるこの事例は、今日のソフトウェアサプライチェーンがいかに脆弱になっているかを示している。このワームは悪意のあるコードを追加するだけでなく、トークンを盗み出し、データを送信し、そして自動的に自己複製を行った。そのため、攻撃は数週間ではなく数時間で拡散した。
開発者とDevOpsチームにとって、そこから得られる教訓は明確だ。
- インストールするたびにコードが実行されます。 一般的なnpmパッケージでさえ、インストール後にワームを仕込む可能性がある。
- どのトークンも高い価値を持っている。 一度盗まれると、マルウェアをさらに拡散するために悪用される可能性がある。
- あらゆる pipeline 確認が必要です。 無し guardrails 依存関係、ワークフロー、および機密情報に関しては、1つの妥協がすぐに本番環境に影響を与える可能性があります。
したがって、Shai-Huludのような攻撃を阻止するには、自動化され、容易に実施できる制御策が必要です。チームは、インストール前にnpmパッケージをスキャンし、ロックファイルビルドを使用し、不審な公開アクティビティを検出し、トークンの有効期限を短くする必要があります。これらの手順はもはやオプションではなく、現代のシステムにおける回復力の基盤となります。 pipelines.
Xygeni では、Shai-Hulud サプライチェーン攻撃をオープンソースエコシステム全体への警告と捉えています。持続可能な前進の道は、コード、npm パッケージ、そしてサプライチェーンセキュリティを開発プロセスに直接組み込むことです。 pipelines が接続します。
以下は、Shai-Huludで侵害されたと報告されているnpmパッケージとバージョンの全リストです。これを使用して、ロックファイル、レジストリ、およびCIをチェックしてください。 pipeline露出のためのs。
侵害されたパッケージのリスト
📦 侵害されたnpmパッケージのプレビュー
| パッケージ名称 | 公開日 | |
|---|---|---|
| json-rules-engine-simplified | 0.2.1 | 2025-09-14T17:58:51.203Z |
| パイロット | 0.8.8 | 2025-09-14T18:35:07.600Z |
| mcp知識グラフ | 1.2.1 | 2025-09-14T18:35:09.494Z |
| 空軍司令官 | 0.3.1 | 2025-09-14T18:35:09.521Z |
| ジャンプゲート | 0.0.2 | 2025-09-14T18:35:09.651Z |
| tvi-cli | 0.1.5 | 2025-09-14T18:35:10.996Z |
| @thangved/callback-window | 1.1.4 | 2025-09-14T20:31:38.479Z |
| @tnf-dev/api | 1.0.8 | 2025-09-14T20:31:39.547Z |
| @tnf-dev/js | 1.0.8 | 2025-09-14T20:31:41.251Z |
| @tnf-dev/mui | 1.0.8 | 2025-09-14T20:31:41.259Z |
| @tnf-dev/core | 1.0.8 | 2025-09-14T20:31:42.728Z |
| @teselagen/react-table | 6.10.20 | 2025-09-14T20:37:08.597Z |
| @hestjs/demo | 0.1.2 | 2025-09-14T20:45:52.348Z |
| @nexe/eslint-config | 0.1.1 | 2025-09-14T20:45:53.625Z |
| @hestjs/eslint-config | 0.1.2 | 2025-09-14T20:45:55.044Z |
| @nexe/config-manager | 0.1.1 | 2025-09-14T20:45:55.066Z |
| @nexe/logger | 0.1.3 | 2025-09-14T20:45:55.170Z |
| @hestjs/logger | 0.1.6 | 2025-09-14T20:45:55.197Z |
| @hestjs/validation | 0.1.6 | 2025-09-14T20:45:55.595Z |
| @hestjs/core | 0.2.1 | 2025-09-14T20:45:55.888Z |
➡️ 侵害されたパッケージの全リストを表示
| パッケージ名称 | 公開日 | |
|---|---|---|
| json-rules-engine-simplified | 0.2.1 | 2025-09-14T17:58:51.203Z |
| パイロット | 0.8.8 | 2025-09-14T18:35:07.600Z |
| mcp知識グラフ | 1.2.1 | 2025-09-14T18:35:09.494Z |
| 空軍司令官 | 0.3.1 | 2025-09-14T18:35:09.521Z |
| ジャンプゲート | 0.0.2 | 2025-09-14T18:35:09.651Z |
| tvi-cli | 0.1.5 | 2025-09-14T18:35:10.996Z |
| @thangved/callback-window | 1.1.4 | 2025-09-14T20:31:38.479Z |
| @tnf-dev/api | 1.0.8 | 2025-09-14T20:31:39.547Z |
| @tnf-dev/js | 1.0.8 | 2025-09-14T20:31:41.251Z |
| @tnf-dev/mui | 1.0.8 | 2025-09-14T20:31:41.259Z |
| @tnf-dev/core | 1.0.8 | 2025-09-14T20:31:42.728Z |
| @teselagen/react-table | 6.10.20 | 2025-09-14T20:37:08.597Z |
| @hestjs/demo | 0.1.2 | 2025-09-14T20:45:52.348Z |
| @nexe/eslint-config | 0.1.1 | 2025-09-14T20:45:53.625Z |
| @hestjs/eslint-config | 0.1.2 | 2025-09-14T20:45:55.044Z |
| @nexe/config-manager | 0.1.1 | 2025-09-14T20:45:55.066Z |
| @nexe/logger | 0.1.3 | 2025-09-14T20:45:55.170Z |
| @hestjs/logger | 0.1.6 | 2025-09-14T20:45:55.197Z |
| @hestjs/validation | 0.1.6 | 2025-09-14T20:45:55.595Z |
| @hestjs/core | 0.2.1 | 2025-09-14T20:45:55.888Z |
| @hestjs/cqrs | 0.1.6 | 2025-09-14T20:45:55.966Z |
| @hestjs/スカラー | 0.1.7 | 2025-09-14T20:45:56.386Z |
| ng2 ファイルアップロード | 7.0.3 | 2025-09-15T02:44:29.555Z |
| コンデンサ通知ハンドラ | 0.0.2 | 2025-09-15T04:54:48.431Z |
| コンデンサープラグインVonage | 1.0.2 | 2025-09-15T04:54:48.501Z |
| コンデンサープラグインヘルスアプリ | 0.0.2 | 2025-09-15T04:54:48.704Z |
| コンデンサーアンドロイドパーミッション | 0.0.4 | 2025-09-15T04:54:48.753Z |
| voip-callkit | 1.0.2 | 2025-09-15T04:54:49.223Z |
| コンデンサープラグインiHealth | 1.1.8 | 2025-09-15T04:55:08.113Z |
| @art-ws/common | 2.0.22 | 2025-09-15T05:21:15.411Z |
| @art-ws/config-eslint | 2.0.4 | 2025-09-15T05:21:17.199Z |
| ngx-ws | 1.1.5 | 2025-09-15T05:21:17.514Z |
| @art-ws/slf | 2.0.15 | 2025-09-15T05:21:17.524Z |
| @art-ws/http-server | 2.0.21 | 2025-09-15T05:21:17.745Z |
| pm2-gelf-json | 1.0.4 | 2025-09-15T05:21:18.413Z |
| @art-ws/di | 2.0.28 | 2025-09-15T05:21:18.488Z |
| @art-ws/di-node | 2.0.13 | 2025-09-15T05:21:18.849Z |
| @art-ws/config-ts | 2.0.7 | 2025-09-15T05:21:19.408Z |
| @art-ws/db-context | 2.0.21 | 2025-09-15T05:21:19.814Z |
| @art-ws/openapi | 0.1.9 | 2025-09-15T05:21:19.969Z |
| @art-ws/web-app | 1.0.3 | 2025-09-15T05:21:20.383Z |
| @art-ws/ssl-info | 1.0.9 | 2025-09-15T05:21:20.927Z |




