Node-gypサプライチェーン侵害:binding.gypに潜む自己増殖型npmワーム
2026年6月4日
30 分で読めますセキュリティツールのbinding.gypをpreinstallやpostinstallのbinding.gypをnpm install時にnode-gypを
ペイロードは
要約
攻撃の | 侵害された |
新たな |
|
Snykに | |
深刻度 | 重大 |
インシデント発生日 | 202 |
侵害された | 57パッケージ、 |
ダウンロード数が |
|
マルウェアの | 認証情報の |
直ちに | 安全が |
影響を受けるパッケージ
Snykは@vapi-ai/server-sdkのregistry.npmjs.orgから
パッケージ | 週間ダウンロード数 | 悪意ある |
|---|---|---|
約86,500 | 0.11.1、0.11.2、1.2.1、1.2.2 | |
約36,900 | 0.13.1、1.1.1、2.2.1、3.8.5 | |
約5,900 | 2.26.4、3.4.3 | |
約280 | 1.33.3 |
57件のautotelおよびautotel-*パッケージで、jagreehalに@jagreehal/*スコープとawaitlyも
autotel-*ファミリー(24パッケージと autotel本体): autotel-mcp(0.1.14から29.0.1までのバージョンを 含む)、 autotel-subscribers、autotel-terminal、autotel-mongoose、autotel-eventcatalog、autotel-devtools、autotel-aws、autotel-cloudflare、autotel-hono、autotel-playwright、autotel-sentryなどeslint-plugin-executable-stories-*ファミリー(Snykは 以前、ESLint-plugin npmサプライチェーンマルウェアを 取り上げています) @jagreehal/*パッケージ@evolvconsulting/evolv-coder-lite
バージョン番号がautotel-mcpが29.xにまでautotelの2.26.4と3.4.3の
修復にlatestのautotelのlatestは3.4.2をautotel@3.4.3とautotel@2.26.4のnpm install autotelをlatestタグが
攻撃の仕組み
新たな手法:binding.gypを介したインストール時の実行
binding.gypファイルをnpm installをnode-gypにnode-gyp rebuildをpackage.jsonのpreinstallやpostinstallの
GYPの<!(...)形式は@vapi-ai/server-sdk@1.2.2とautotel@3.4.3にbinding.gypです
<!(node index.js ...)式は、node-gypがnode index.jsを"type": "none"ターゲットではindex.jsの/dev/nullにecho stub.cは、npm install中に
重要なのは、package.jsonにpreinstall、postinstall、install、prepareのscriptsにbuild、lint、test、formatと"gypfile": trueのpackage.jsonにはbinding.gypファイルがnode-gypを
ペイロード:Bunを利用した多段階ローダー
binding.gypがindex.jsは、
ROT-14シーザー暗号。ファイル全体は、
約130万個の 文字コードを 並べた 配列に 対する 単一の evalで、配列を 文字列に 変換してから 14文字分ずらします。 目に 見える ラッパーは、 文字どおり eval(function(s,n){return s.replace(/[a-zA-Z]/g,...rotate...)}([...],14))です。AES-128-GCMに
よる 自己復号レイヤー。復号された 段階は asyncIIFEで、node:cryptoを読み込み、 aes-128-gcmの復号器 (16バイトの 認証タグを 使う createDecipheriv)を定義します。 その後、 16進数形式の キー、 IV、 認証タグが コード内に ハードコードされた、 埋め込み型の 暗号文ブロブ2つを 復号します。 Bunランタイムローダー
(907バイトの ブロブ)。最初に 復号された ブロブは OSと アーキテクチャを 検出し、 公式の oven-sh/bunGitHubリリースからスタンドアロンのBun v1.3.13バイナリを 一時 ディレクトリに ダウンロードして 実行します。
メインペイロード
(約649 KBの ブロブ)。2つ目に 復号された ブロブ (664,535バイト)は、 窃取処理そのものです。 インストールを 開始した Node.jsプロセスではなく、 ダウンロードされた Bunバイナリ上で 実行されます。
インストールをnodeプロセスではなく、npm install中のindex.jsを
認証情報の収集
実行されると、
AWS:
aws_access_key_id/aws_secret_access_key、およびIMDSv2メタデータエンドポイント ( 169.254.169.254)GCP:
GOOGLE_APPLICATION_CREDENTIALSおよびサービスアカウントキーAzure:IMDS経由の
マネージドIDトークン GitHub Actions:
ACTIONS_ID_TOKEN_REQUEST_TOKENに加え、 ランナープロセスの メモリを スクレイピング HashiCorp VaultおよびKubernetes:標準パスに
ある サービスアカウントトークン パスワードマネージャー:1Password、
pass、gopassのストア
GitHub Actionsでは、
GitHub Actionsの
GitHubリポジトリ経由の窃取データ送信
マルウェアはliuende501(執筆時点で
ハードコードされた
キーワードで 公開コミットを 検索し、 ランデブーポイントを 見つける ランダムな
名前を 付けて リポジトリを その 場で 作成する 暗号化した
収集データを results/results-{timestamp}.jsonとして アップロードする python-requests/2.31.0のUser-Agentを 付けて APIリクエストを 送信する
GitHubをgithub.comやapi.github.comへの
エコシステムをまたぐワームの拡散
ペイロードは
npmワーム:
registry.npmjs.org/-/v1/search?text=maintainer:{username}を使って メンテナーの パッケージを 列挙し、 対象を ダウンロードして 悪意ある binding.gypとindex.jsを注入し、 再公開します。 この ファミリーの 過去の 波 (SLSA来歴証明が 有効な、 初の 悪意ある npmパッケージを 取り上げた SnykのTanStackに 関する 解説を 参照)と 同様に、 ワームは Fulcioと Rekorを 通じて Sigstoreの 来歴証明も 偽造し、 再感染した パッケージが 正規の 署名付きに 見えるようにします。 RubyGemsワーム:RubyGemsの
ネイティブ拡張ビルドフックである extconf.rbに同等の ロジックを 注入し、 同じ Bunダウンローダーを 再利用します。 extconf.rbはRubyGemsに おいて、 npmの binding.gypに相当します。 どちらも ビルド時に 自動実行される ファイルであり、 ライフサイクル上の 「スクリプト」ではありません。 GitHubリポジトリの
汚染:窃取した トークンで 書き込み可能な リポジトリに バックドアファイルを コミットします。 AIコーディングエージェントや エディターの フック ( .claude/、.cursor/rules/、.vscode/tasks.jsonなど)も含まれ、 開発者が プロジェクトを 開くと ペイロードが 再実行されます。
npmと
影響分析
直接的なnpm installを
開発者マシンには、npm uninstallでは
キャンペーンのautotelおよびautotel-*のjagreehalを
検出
Snykで
特定の
パッケージ名だけでなく、binding.gypである
ネットワークおよび
正当な
ネイティブアドオンを 含まない パッケージで node-gyp rebuildが実行されている npm install中に予期しない 子プロセス ( curl、unzip、bun)が起動する Bunを
要求していないのに、 インストール中に oven-sh/bunのリリースから 単体の bunバイナリがダウンロードされる Pythonプロセスではない
CIステップから、 User-Agentが python-requests/2.31.0のGitHub API 呼び出しが 発生する
修復
影響を
ステップ1:トークンを
ステップ2:クリーンアップし、
--ignore-scriptsを--ignore-scriptsを
ステップ3:影響を
npm
公開トークン GitHubの
個人用アクセストークンと Actionsシークレット (リポジトリおよび組織スコープ) AWSアクセスキー、
および影響を 受けた ランナーから アクセス可能な IAMロール GCPサービスアカウントキー
Azureサービスプリンシパルと
マネージドIDの スコープ HashiCorp Vaultトークン
Kubernetesサービスアカウントトークン
標的と
なった パスワードマネージャーの 保管庫内に ある すべての 情報 (1Password、 pass、gopass)
ステップ4:GitHubを
ステップ5:次の
CIでは
デフォルトで npm install --ignore-scriptsを使用し (インストール時攻撃全般への ベストプラクティス)、 スキャンゲートと 併用する ロックファイルの
整合性ハッシュを 使い、 依存関係を 厳密な バージョンに 固定する 公開から
数日以内の パッケージを ビルドに 使用する 前に 保留する、 レジストリの クールダウンポリシーを 検討する CI/CDトークンに
最小権限の スコープを 適用し、 トークンが 1つ 窃取されても 影響範囲を 小さく 抑える Snykを
使って 依存関係 ツリーを 継続的に 監視し、 悪意の ある パッケージが 特定されたら すぐに 把握する
Snykのnpmサプライチェーン攻撃を
全体像:Shai-Huludの亜種
これは
初期の
攻撃では preinstall/postinstallライフサイクルスクリプトが使われていました その後の
攻撃では、 永続化の ために AIコーディングエージェントの フック ( SessionStart)や IDEの フォルダーを 開いた ときに 実行される タスクが 追加されました 今回の
攻撃では、初回の 実行を binding.gyp/node-gyp(RubyGemsではextconf.rb)に移しています。 これらは ビルド時の ファイルであり、 ライフサイクルスクリプトではありません。
Snykは、
今回の
Snykの
Snykを
Snykの
正規の
タイムライン(UTC)
日付 | 出来事 |
|---|---|
202 | 先行するMiasma亜種が、 |
202 | 主な |
202 | 「Phantom Gyp」手法の |
継続中 | 調査は |
Snykの対応
Snykは
Snyk Vulnerability DBを チェック
信頼できる



