誰かが登録しました tanstack npmに登録され、「TanStack Player」と名付けた動画プレイヤーSDKを開発し、本日、実行された瞬間に環境ファイルを盗み出すように設計された4つのバージョンを立て続けに公開した npm install.
本物のTanStack――TanStack Query、TanStack Table、TanStack Routerなど、これらすべてが揃う場所 @tanstack/* 毎週数百万回もダウンロードされているパッケージとは、何の関係もない。攻撃者は単にスコープのない名前を拾い上げ、それを見事に偽装して、ただ待ち構えていたのだ。
本日17時08分(UTC)に、彼らはペイロードを展開した。
何が起きたのか
2026年4月29日 17:08~17:35(UTC)の間に、 tanstack npmパッケージとして、2.0.4、2.0.5、2.0.6、および2.0.7が公開されました。これら4つすべてに postinstall パッケージのインストール時に自動的に実行されるフック。
今日までは、 tanstack@2.0.3 (3月に発行された)には postinstall hook。ネットワーク呼び出しのない、すっきりとしたパッケージでした。しかし、今日それが変わりました。
会社情報 postinstall.cjs このスクリプトは、開発者の作業ディレクトリから環境ファイルを読み取り、その内容を攻撃者が制御するSvix Webhookエンドポイントに送信します。ユーザーへのプロンプトは表示されず、ほとんどのバージョンでは目に見える出力もありません。実行されるとすぐに終了します。
このキャンペーンが始まる前の1か月間で、このパッケージのダウンロード数は約19,830件でした。
ペイロード
スクリプトの仕組みは単純明快です。インストール時、ローカルファイルを読み込み、それらをJSON形式でこのエンドポイントにPOSTします:
https://api.svix.com/ingest/api/v1/source/src_3387PLMB2uhXOBe3Q8sHu/in/3j2jokvbaF4WWdngv8zBbk
Svixは、正規のWebhooks-as-a-Service(WaaS)企業です。攻撃者は同社の「Ingest」製品をデータ流出の中継点として利用し、盗んだデータを信頼できる第三者経由で転送することで、ネットワークレベルでの遮断を回避しています。
ペイロードには、ファイルの内容に加え、システムのメタデータが含まれています:
{
"package": "tanstack",
"version": "2.0.x",
"event": "postinstall",
"readme": "<contents of .env>",
"agents": "<contents of .env.local>",
"timestamp": "...",
"node": "v22.x.x",
"platform": "linux",
"arch": "x64"
}フィールド名(readme, エージェント) は目くらましに過ぎない。🪄 実際に送られているのはあなたの .env そして .env.local.
4つのバージョン、27分間、1人の攻撃者による実環境でのテスト
この事件において、最も興味深いのはバージョン履歴だ。攻撃者は30分足らずの間に4つのリリースを公開し、プッシュのたびにペイロードを明らかに改良していた。
2.0.4 (17:08): ターゲット .env そして .env.local. オプトアウトのチェック(TANSTACK_TELEMETRY_OPT_OUT) はコメントアウトされており、つまり逃げ道がないことを意味します。重複が含まれています postinstall.js 他のバージョンには含まれていないファイル。以下の内容をインポートします。 http モジュールはあるが、一度も使用されていない。
2.0.5 (17:11、3分後):対象ファイルを以下に変更します README.md そして AGENTS.mdまた、オプトアウト機能も再有効化されます。これは一時的な迂回のように見えます――Webhookがデータを受信しているかどうかをテストしているか、あるいは本筋に戻る前に、その動作をより無害なものに見せようとしているかのどちらかでしょう。 README.md これは認証情報ファイルではありません。
2.0.6 (17:26): 危険なバージョン。対象のファイルパスを完全に削除し、ディレクトリ全体のスキャンに置き換えます:
function collectEnvFiles() {
const allFiles = fs.readdirSync(rootDir);
const matches = allFiles.filter(
(f) => f === ".env" || f.startsWith(".env.")
);
for (const file of matches) {
envFiles[file] = fs.readFileSync(path.join(rootDir, file), "utf-8");
}
return envFiles;
}これで全てを網羅できます: .env, .env.local, .env.production, .env.staging, .env.development. すべてが1つのPOSTリクエストで送信されます。コンソールへの出力は完全に抑制されます。オプトアウトの記述は再びコメントアウトされています。
2.0.7 (17:35): 以前の状態に戻す .env + .env.local ターゲット指定により、コンソール出力がコメントアウトされたままになります。奇妙な自己参照的な依存関係が追加されます "tanstack": "^2.0.6" 独自の package.json 内に記述されています。これがミスなのか、それとも何らかの目的があるのかは不明です。
このバージョン履歴で目にするのは、リアルタイムのデバッグの様子です。攻撃者は、パッケージが一般に公開され、インストール可能な状態にある間、標的を調整し、受信機をテストし、ステルス性を高めるための最適化を行っていました。
スクワット角度
会社情報 @tanstack この組織は、npm上で最も広く利用されているJavaScriptライブラリのいくつかを公開しています。TanStack Queryだけでも、週に約800万回のダウンロードがあります。 tanstack unscoped nameは、2024年12月以来、別個に扱われてきた。
実行中の開発者 npm install tanstack ~の代わりに npm install @tanstack/query 期待していたものとは違ってしまう。結局、こうなってしまうのだ。
このパッケージのREADMEは洗練されています。スポンサーバッジ、npmダウンロードのシールド、機能比較表、コード例などが掲載されており、まるで本物の製品のように見えます。その見栄えは、ざっと見ただけでは偽物だと気づかないほどです。
何が盗まれるのか
一般的なJavaScriptプロジェクトでは、 .env ファイルには以下の内容が含まれています:
- AWSのアクセスキーとシークレット
- GitHubの個人用アクセストークン
- npm パブリッシュ トークン
- データベース接続文字列
- Stripe、Twilio、Resend、SendGridAPI
- OpenAI、Anthropic、およびその他のLLMAPI
- OAuthクライアントシークレット
- ローカルに設定されているその他のサードパーティの認証情報
もしあなたが .env.production 作業ディレクトリの近くにあるファイル(バージョン2.0.6であれば検出できたはず)に、本番環境の認証情報が保存されている場合、インストール時にその情報が攻撃者に渡されてしまいます。
修復と検出
手順 1:影響を受けたかどうかを確認する
ロックファイルとインストール履歴を確認し、以下のパッケージのバージョンが含まれていないか確認してください:
# package-lock.json を確認する
grep -r "tanstack" package-lock.json yarn.lock pnpm-lock.yaml 2>/dev/null
# node_modules を確認
ls node_modules/tanstack/package.json 2>/dev/null && cat node_modules/tanstack/package.json | grep '"version"'対象バージョン: 2.0.4, 2.0.5, 2.0.6, 2.0.7. ロックファイルにこれらのいずれかが含まれている場合は、環境ファイルが侵害されたものとみなしてください。
ステップ2:影響を受けた場合
任意の .env file present in the working directory at install time was exfiltrated. Rotate immediately:
- AWSのアクセスキーとシークレット 不正なAPI についてはCloudTrailを確認してください)
- リポジトリまたは組織スコープのGitHubトークン
- npmトークン — npmjs.com/settings で無効化し、再発行してください
- に存在するデータベースの認証情報
.env - 影響を受けるファイル内のすべてのサードパーティ製API
CI環境の場合:postinstallは以下のタイミングで実行されます npm ci また、CIパイプラインがこのパッケージをインストールしていた場合は、そのパイプラインの環境にシークレット すべてのシークレット 更新してください。侵害が発生した時期のインストール手順について、CIプロバイダーのジョブログを確認してください。
開発者向けマシンについて:これはメモリ内攻撃ではなく、永続的なデータ流出です。ファイルが読み取られ、送信されました。削除されたバイナリや後始末が必要な永続化メカニズムはありませんが、認証情報はすでに外部に流出しています。
以下の宛先へのHTTPS送信トラフィックを確認してください api.svix.com インストール時のネットワークログを確認してください。そのPOSTリクエストは、インストールを実行していたCIランナーまたは開発者のマシンから送信されたものと思われます。
ステップ3:次の方法で検出する Aikido
Aikidoユーザーの場合、中央フィードを確認し、マルウェアの問題でフィルタリングしてください。この脆弱性は、フィード内で100/100のクリティカルな問題として表示されます。ヒント:Aikidoはリポジトリを毎晩再スキャンしますが、フルスキャンもトリガーすることをお勧めします。
Aikidoユーザーでない場合は、アカウントを設定し、リポジトリを接続してください。独自のマルウェアカバレッジは無料プランに含まれており、クレジットカードは不要です。
ステップ4:将来の保護(SafeChain)
将来に備えて、以下の利用をご検討ください Aikido SafeChain(オープンソース)の導入をご検討ください。これは、npm、npx、yarn、pnpm、pnpx向けのセキュアなラッパーです。SafeChainは現在のワークフローに組み込まれ、パッケージのインストールコマンドをインターセプトし、 Aikido Intel を使用してマルウェアの有無を確認します。脅威がマシンに到達する前に阻止しましょう。
IOCs
tanstack@2.0.4— SHA256:72ec4571e27c06f1d48737477c2b38a4f90d699950dab8946b48591133dc4f90tanstack@2.0.5— SHA256:04ee5325c8900c9d644ed81c9012525b6fc19f21c65cef85b6ba98b6a0a23566tanstack@2.0.6— SHA256:abc164807947b102164488a08161adb4ee08be6b78a371350a6b156eed0d97d9tanstack@2.0.7— SHA256:7bb84e6ba893248814cd3bac70b7bdc115740fba9e13419940c73460cbcd7b6f- 情報流出の終端点:
hxxps://api.svix[.]com/ingest/api/v1/source/src_3387PLMB2uhXOBe3Q8sHu/in/3j2jokvbaF4WWdngv8zBbk - Svix ソースID:
src_3387PLMB2uhXOBe3Q8sHu - npm メンテナアカウント:
sh20raj
閉会
この攻撃は、ドメイン乗っ取りの仕組みが、ほんのわずかな手間で、実際に認証情報を収集するツールへと変貌してしまうことを改めて思い知らせてくれる。攻撃者は、メンテナンス担当者を乗っ取ったり、CIシステムをフィッシング攻撃で狙ったり、脆弱性 エクスプロイト する必要さえなかった。彼らは、一見正当なパッケージを登録し、1ページ分のインストール後スクリプトを追加し、インストールが行われるのを待つだけだった。
4段階にわたる反復パターンは注目に値する。これは単発の攻撃ではなかった。攻撃者は現場に潜伏し、状況を注視しながら、ペイロードをリアルタイムで調整していた。これは、自分のやっていることを熟知しており、特に認証情報の網羅性を高めるよう最適化を図っていた人物によるものだ。
すべての .env プロジェクト内のファイルはターゲットとなります。postinstallフックを持つパッケージであれば、どれでもこれを読み取ることができます。npmレジストリでは、デフォルトですべての発行者にこの機能を提供しています。

