何が起きたのか
2026-08-04 09:35 UTC、npm レジストリに [email protected] が公開されました。このバージョンには preinstall ライフサイクルフックが仕込まれており、パッケージのコードを一度も import しなくても、npm install を実行しただけでマルウェアが走ります(Snyk 2026-08-04)。
keyv は週あたり約 1 億 5,370 万ダウンロード、同じメンテナが管理する flat-cache が約 1 億 4,990 万、file-entry-cache が約 1 億 4,760 万(StepSecurity 2026-08-04)。ESLint など広く使われるツールチェーンの間接依存として、多数の開発環境に入り込む位置にあります。
そして、この攻撃で最も読者に近い部分がここです。第2段ペイロードは .claude/settings.json の SessionStart フックと .vscode/tasks.json の runOn: "folderOpen" に自身を再実行させる記述を書き込み、AI コーディングツールや IDE の起動をトリガーにした永続化を試みます。さらに .claude/credentials.json、.cursor/credentials.json、.openai/auth.json、.anthropic/auth.json といった AI ツールの認証情報を明示的な窃取対象に含めていました(StepSecurity 2026-08-04、Snyk 2026-08-04)。
分単位のタイムライン
Snyk は UTC の分単位で経緯を記録しています(Snyk 2026-08-04)。
- 09:02–09:17 コミット
ee2681a9が[email protected]を準備し、ライフサイクルフックとペイロードを追加 - 09:04 コミット
d8c850c7が Claude と VS Code の実行フックを追加 - 09:23 コミット
f97eabcdが preinstall のテストを削除 - 09:30–09:32
@keyv/*の v6 系が公開(Snyk がスナップショットを取った時点の tarball には悪意あるフックが入っていませんでした。ただし SafeDep は 09:39:45 に@keyv/*全体へペイロードが追加されたと記録しており、これらの 6.0.0 は最終的に GitHub がマルウェア指定し npm から削除されています。GHSA-q99r-cjmf-3xrf、GHSA-4wfp-qcf3-mgqp) - 09:35
[email protected]を公開 - 09:49–09:51 GitHub の issue #2044〜#2046 で報告が上がる
- 10:09–10:14 cacheable 系の汚染リリースが連続公開
- 10:28
[email protected]が同一ペイロードで公開 - 10:39–11:11 npm から3パッケージが削除開始
- 11:16 時点で8つの汚染リリースが依然
latestタグ
Snyk が初期に特定した汚染リリースは 11 件で、[email protected]、[email protected]、[email protected]、[email protected]、[email protected]、[email protected]、@cacheable/[email protected]、@cacheable/[email protected]、@cacheable/[email protected]、@cacheable/[email protected]、[email protected] が挙がっています。Socket は file-entry-cache を 11.1.7 として記載しており、ベンダー間で表記が一致していない点は注意が必要です(Socket 2026-08-04)。
署名が正しかったのに、なぜ止まらなかったのか
この事案で技術的に重いのは、npm の provenance(来歴証明)が正規のまま通ってしまった点です。
攻撃者は npm のトークンを盗んで直接 publish したのではなく、メンテナの GitHub アカウントを乗っ取り、main ブランチに直接プッシュしてから即座にリリースを切りました(Aikido 2026-08-04、Wiz 2026-08-04)。その結果、npm のマニフェスト上では [email protected] の trusted publisher は GitHub Actions として記録され、attestation も付きます。Snyk はこの状態を、正規のワークフローが悪意ある成果物をビルドして attest した、と表現しています。
つまり provenance が証明するのは「どのリポジトリ状態の、どのワークフローからビルドされたか」であって、その中身が安全かどうかではありません。リポジトリの状態自体が汚染されていれば、SLSA 由来の provenance は汚染された成果物をそのまま忠実に証明します。provenance は攻撃者による直接 publish や経路の偽装を防ぐ有効な仕組みですが、これを単独で安全性の判定材料に使うと、検証をパスした事実が誤った安心につながります。
コミット偽装も重ねられていました。フックファイルを追加したコミットは GitHub 上で verified 表示になり、author は github-actions[bot] です(Snyk 2026-08-04)。コミットメッセージは chore: update config に変えられており(Wiz 2026-08-04)、SafeDep は、このコミットに Co-authored-by: claude というフッターが付いていたと記録しています(SafeDep 2026-08-04)。AI エージェントによる自動コミットが日常になった環境では、この見た目は疑われにくくなります。
Bun と Ethereum を使った実行・通信
第1段の setup.mjs は 29,918 バイト、SHA-256 は 54dc7ea54a1317cca0e890a2770630cf7fa6c97813e0cb9d2caa93012b350668。第2段の Math_Symbol.js は 727,680 バイト、SHA-256 は 9fc2570b7cef51c1b8df116d144d11ff4096357be7d2c4c6367cfc2509cf1bcc です(Snyk 2026-08-04)。
setup.mjs は oven-sh/bun の GitHub リリースから Bun v1.3.13 を取得し、その Bun で第2段を実行します。Datadog は、この取得が暗号学的な検証を伴わず、bun --version が成功しさえすれば bun という名前の実行ファイルを何でも受け入れる実装だと指摘しています(StepSecurity 2026-08-04、Datadog Security Labs 2026-08-04)。GitHub からの正規バイナリ取得なのでネットワーク上の指標は正当に見え、Node.js のプロセスだけを対象にした監視は回避されうる構成です。
C2 ドメインの解決には EtherHiding が使われています。Ethereum メインネットのコントラクト 0xE1f2395ee43e45A1556EC6438a88c31B83493103 を 75 の公開 RPC エンドポイント経由で照会し、そこから接続先を得る方式で、観測された exfiltration 先は npm-cache.com の 443 番ポート /router でした(StepSecurity 2026-08-04、Datadog Security Labs 2026-08-04)。
この構成が厄介なのは冗長性です。各 RPC エンドポイントが独立に確率 $p$ で遮断されるとしても、$n = 75$ 本すべてを同時に潰せる確率は $p^{75}$ にすぎません。仮に 9 割を落とせても $0.9^{75} \approx 3.7 \times 10^{-4}$ で、残り 1 本が生きていれば解決は成立します。これは遮断が独立に起きると仮定した模式計算で、実際には DNS・ASN・プロバイダの共通性による相関があるためこの数字どおりにはなりませんが、単一ドメインの sinkhole という従来の打ち手が効きにくい理由の見当はつきます。Datadog は補助経路として GitHub のコミット検索を使うフォールバックも確認しています。
自己増殖と、割れている被害件数
第2波は 09:38 UTC から自動再公開として始まりました。StepSecurity は 13:20 UTC 時点の集計として、追加で 433 パッケージ・2,201 バージョンが公開され、全体では 444 パッケージ・2,212 バージョンに達したとしています(同社はこの時点でも件数は増加中だと注記しています)。ペイロードには publish 機能が内蔵されており、被害者が publish 権限を持つパッケージを列挙し、既存の tarball を取得してフックを注入し、sha512 と sha1 の integrity 値を再計算したうえで、自己生成した Sigstore / SLSA provenance を添えて再公開します。StepSecurity はこの連鎖を「どのホップでも攻撃者側のインフラを必要としない」と表現しています。増殖のループ自体が被害者の認証情報と npm の正規公開経路だけで完結するという意味であり、C2 の解決や情報の送信には Ethereum の RPC、外部ドメイン、GitHub を使っている点は変わりません(StepSecurity 2026-08-04)。
第2波の平均公開レートは、
$$\lambda = \frac{433\ \text{packages}}{13{:}20 - 09{:}38} = \frac{433}{222\ \text{min}} \approx 1.95\ \text{packages/min}$$となり、人手による対応の速度を明確に上回ります。
一方、被害件数はベンダー間だけでなく、一次発表と報道の間でも割れています。The Hacker News の整理では、SafeDep が検証済みとして 79 パッケージ名・353 バージョン、同じ SafeDep のモニタリングによる広い範囲の集計が 353 パッケージ名・442 バージョン、Aikido が「少なくとも 868 パッケージ・1,381 バージョン」と伝えられています(The Hacker News 2026-08-04)。ただし Aikido 自身のブログは 2026-08-04 13:37 CEST の更新で「少なくとも 434 パッケージ(1,381 バージョン)」としており、868 という数字は Aikido の一次発表には見当たりません(Aikido 2026-08-04)。SafeDep の 2 系統の数字も、私が確認できた範囲では The Hacker News の記述でしか裏が取れていません。集計基準(パッケージ名で数えるか、バージョン成果物で数えるか、観測時刻はいつか)が揃っておらず、報道側での取り違えも起こりうる状態です。The Hacker News は、これらが汚染された成果物の数であって被害システム数ではない、と明示しています。
命名も統一されていません。StepSecurity は ChainDrop と呼び、Datadog はペイロード内の文字列から Shai-Hulud: Here We Go Again という自称を確認しています。
Claude Code / VS Code ユーザーが今日確認すべきこと
Socket が示している手順のうち、手元の開発機で意味があるものを整理します(Socket 2026-08-04)。
まず、汚染バージョンが依存ツリーや lockfile に入っていないかを見ます。フックだけを grep しても、間接依存として引き込まれた該当バージョンは見つかりません。
# 1. 該当パッケージが依存ツリーのどこに入っているか
npm ls keyv flat-cache file-entry-cache cacheable cacheable-request \
cache-manager @cacheable/utils @cacheable/net @cacheable/node-cache \
@cacheable/memory ecto --all
# 2. lockfile に汚染バージョンが固定されていないか
grep -nE 'keyv|flat-cache|file-entry-cache|cacheable|cache-manager|ecto' \
package-lock.json pnpm-lock.yaml yarn.lock 2>/dev/null
そのうえで、IDE のフックと第2段ペイロードの痕跡を見ます。
grep -r "SessionStart" ~/.claude/settings.json .claude/settings.json
grep -r "folderOpen" ~/.vscode/tasks.json .vscode/tasks.json
find ~ -name "Math_Symbol.js" -o -name "math_init.js" -o -name "setup.mjs"
次に永続化コンポーネントです。Snyk と Socket は gh-token-monitor という仕組みを挙げています。これは盗んだ GitHub トークンを監視し、トークンが失効したときにハンドラを起動する構造で、~/.local/bin/gh-token-monitor.sh、~/.config/gh-token-monitor/、Linux では ~/.config/systemd/user/gh-token-monitor.service、macOS では ~/Library/LaunchAgents/com.user.gh-token-monitor.plist を確認対象としています。
Socket が強調しているのは順序です。この仕組みは失効を検知して動くため、先に除去してから認証情報を無効化する必要があります。そのうえで npm トークンと GitHub の PAT / GITHUB_TOKEN については「ローテーションするだけでなく revoke せよ」とし、AWS / GCP / Azure の鍵、Vault トークン、Kubernetes のサービスアカウントトークン、CI のシークレットについてはローテーションを指示しています(Socket 2026-08-04)。
依存側は、該当バージョンを避けて exact version で固定し、node_modules を削除したうえで lockfile を integrity ハッシュごと作り直す運用が推奨されています。汚染バージョンが実際にインストールされていた形跡があるなら、grep と再インストールで済ませる範囲を超えます。上の順序(永続化の除去 → 認証情報の失効)を、クリーンな別端末から実行してください。
残された不確実性
汚染件数は出典ごとに 353〜868 パッケージと 2 倍以上開いており(上限側の 868 は The Hacker News の記述で、Aikido 自身は 434 パッケージとしています)、どれが正しいかは現時点で確定できません。集計時刻と数え方の差が大きく、単一の数字を引用するのは適切ではないと考えます。
.claude/settings.json と .vscode/tasks.json のフックが実際に発火する条件も、今回確認した各レポートからは詳細が読み取れませんでした。VS Code の workspace trust の状態によって挙動が変わる可能性は指摘されていますが、私が直接確認できた記述の範囲を超えるため断定しません。
The Hacker News は、報道時点でメンテナ、npm、GitHub のいずれからも公式のインシデント声明が確認できなかったと記しています(The Hacker News 2026-08-04)。Snyk のアドバイザリは SNYK-JS-KEYV-18515941 で、同社は調査時点では CVE も GHSA も未割当だと記しています。ただしその後、GitHub は 2026-08-04 付で keyv の GHSA-3p9h-f68w-m6fx をはじめとするマルウェア勧告を発行しました(@keyv/* と cacheable 系を含む)。CVE は本稿執筆時点でも未割当です。
Claude や Cursor の認証情報が実際にどの程度回収され、どう悪用されたかについては、窃取対象として設定されていた事実までしか確認できていません。
まとめ
2026-08-04 09:35 UTC の [email protected] 公開から約4時間で、数百パッケージが汚染されました。攻撃の中核は目新しい脆弱性ではなく、GitHub アカウント乗っ取りという古典的な入り口です。しかしその先が変わりました。正規のリリースワークフローを経由したため provenance 署名は有効なまま通り、Bun という正規バイナリで実行され、C2 は Ethereum コントラクトから解決され、永続化は AI コーディングツールの設定ファイルに書き込まれました。
署名検証は「誰がどのリポジトリ状態からビルドしたか」を証明しますが、そのリポジトリ状態が正しいかは証明しません。AI エージェントの設定ファイルが実行可能な設定である以上、それは依存関係と同じ攻撃面として扱う必要があります。手元の .claude/ と .vscode/ を一度 grep してみることを勧めます。
主要出典
- Inside the keyv npm Supply Chain Compromise(Snyk、2026-08-04) — UTC 分単位のタイムライン、汚染 11 リリース、setup.mjs と Math_Symbol.js の SHA-256、trusted publisher と attestation の扱い、gh-token-monitor
- ChainDrop npm worm(StepSecurity、2026-08-04) — 444 パッケージ / 2,212 バージョン、第2波の時刻、Bun v1.3.13 ローダー、Ethereum コントラクトと 75 RPC 経由の C2 解決、AI ツール認証情報の窃取範囲
- Worm compromises hundreds of popular npm packages(Datadog Security Labs、2026-08-04) — 独立検証。GitHub コミット検索のフォールバック、AWS 17 リージョン走査、Shai-Hulud: Here We Go Again という自称
- Popular npm Packages in the keyv and Cacheable Namespaces Compromised(Socket、2026-08-04) — preinstall の実物、除去→revoke の順序、確認コマンド
- keyv and cacheable npm Package Hijacked in Supply Chain Attack(Wiz、2026-08-04) — GitHub メンテナアカウント侵害という起点の確認、復旧手順
- Keyv and friends compromised in npm supply chain attack(Aikido、2026-08-04) — 初報。main ブランチ直接プッシュ→即リリース、別集計値
- keyv npm supply chain compromise(SafeDep、2026-08-04) — 秒精度のタイムライン、
Co-authored-by: claudeフッター、gh-token-monitor の 60 秒ポーリング - Keyv-Linked npm Worm Poisons Hundreds(The Hacker News、2026-08-04) — ベンダー別件数の突き合わせ、公式声明が未確認である旨
- jaredwray/keyv(GitHub) — 攻撃の起点となったリポジトリ本体
関連する過去記事
- OpenAIが認めた『モデルがサンドボックスを脱出しHugging Faceに侵入』 — 盗んだ認証情報とゼロデイを連鎖させた事案。認証情報が攻撃連鎖の起点になる構図は今回と共通です
- 141,006ランの調査で6ラン・3件の実害 — 設定不備によって AI エージェントが実在組織へ到達した事例。設定ファイルが実行境界を決めるという論点が重なります
- 『安くなったが本当に賢いのか』を検証する──Gemini 3.6 Flash — モデル側のサイバー能力評価。攻撃側・防御側の自動化速度を考えるうえでの対になる材料です