PaPoo
cover
technews
Author
technews
世界の技術ニュースをリアルタイムでキャッチし、日本語でわかりやすく発信。AI・半導体・スタートアップから規制動向まで、グローバルテックシーンの「今」をお届けします。

npmでまた大規模汚染 317パッケージに悪性版、しかも仕込みがかなり手口が悪い

キーポイント

image_0002.svg

何が起きたのか

SafeDepの記事によると、2026年5月19日、npm のメンテナーアカウント atool が侵害されました。
その結果、​22分という短時間に、317個のパッケージへ637個の悪性バージョンが一気に公開されたそうです。

image_0003.svg

ここで地味に怖いのは、「1パッケージが1回壊れた」のではなく、​広く浅く大量にばらまかれた点です。
たとえば size-sensorecharts-for-reacttimeago.js、さらに @antv スコープ配下の多数のパッケージが含まれていました。
こういう人気パッケージが混じると、依存関係のどこかで使っているだけの人まで巻き込まれます。オープンソース供給網攻撃の典型ですが、毎回「やっぱりそこを突いてくるか」と思わされます。

image_0004.svg

ざっくり言うと、かなり“全部盛り”のマルウェア

今回のペイロードは、ただ情報を抜くだけではありません。
記事では、以下のような機能が確認されています。

image_0005.svg

1. 認証情報をありったけ集める

image_0006.svg

狙う対象が広いです。npmトークン、GitHub PAT、AWSキー、GCP/Azureの認証情報、データベース接続文字列、StripeやSlackのトークン、SSHキー、Docker認証情報、Kubernetesのサービスアカウントトークン、HashiCorp Vault、さらには 1Password や Bitwarden、pass、gopass といったローカルのパスワード管理データまで対象になっているとのこと。

要するに、​​「開発者マシンにあるおいしいものを全部持っていく」​発想です。
個人的にはここが一番いやらしいと思いました。単発のAPIキーを抜く程度ではなく、​次の侵入先まで見据えた情報収集になっているからです。

image_0007.svg

2. 漏えい経路が2本ある

image_0008.svg

盗んだデータは、2つの経路で外に出されます。

image_0009.svg

前者はかなり発想が面白いというか、悪い意味で賢いです。
普通の通信監視だと「GitHubへのコミット」に見えてしまうかもしれない。しかもUser-Agentを python-requests/2.31.0 に偽装しているそうで、雑に見えてけっこう計算されています。

image_0010.svg

3. CI/CD を乗っ取って永続化する

CI環境では、GitHub Actions の OIDCトークンを使ってnpm publish tokenを交換したり、Sigstore(Fulcio + Rekor)で正規っぽい署名付き成果物を作ったりします。
さらに .github/workflows/codeql.yml に仕込んで、toJSON(secrets) を artifact に吐かせるような動きまであるとのこと。

image_0011.svg

これ、単に「感染した」では終わらないのが怖いです。
自動化パイプラインそのものを踏み台にするので、一度入られると後のリリースや解析にも影響が出ます。セキュリティの現場でCIが重要視されるのは、まさにこういう理由です。

image_0012.svg

4. AI開発ツールまで狙う

記事では、Claude Code や Codex、VS Code に対しても仕込みがあるとされています。

image_0014.svg

image_0015.svg

つまり、​人間が明示的に実行しなくても、開いた瞬間やセッション開始時に勝手に動くようにしているわけです。
AIコーディング支援ツールが普及した今、これはかなり現実的な脅威だと思います。開発者体験が便利になるほど、悪用される入口も増える。便利さと危うさは表裏一体です。

5. 永続化までやる

image_0016.svg

さらに kitty-monitor という systemd user service や macOS LaunchAgent を置いて、GitHubを使った dead-drop C2 を構築しているそうです。
dead-drop C2 というのは、ざっくり言うと​「見つかりにくい受け渡し場所を使う遠隔操作の仕組み」​です。

image_0017.svg

しかも、GitHubのcommit search APIを見に行って、特定のキーワード firedalazer を含む署名付きコマンドを探し、それをダウンロードして実行する仕組みまであるとのこと。
かなり執念深いです。普通のマルウェアというより、​長期潜伏を前提にした仕組みに見えます。

どうやって入ったのか

image_0018.svg

記事では、感染した各バージョンに preinstall スクリプトとして bun run index.js が仕込まれていたとされています。
preinstall は、パッケージを入れる前に実行される処理です。つまり、​インストールしただけで走る。これが本当に厄介です。

image_0019.svg

さらに 637 個のうち 630 個では、optionalDependenciesgithub:antvis/G2#<commit-sha> を入れて、GitHub上の「見えにくい別のコピー」からもペイロードを配る設計だったそうです。
このあたりは、かなり悪意が洗練されています。
GitHubのfork object sharing を悪用して、対象リポジトリの通常の履歴から見えにくいコミットを使う、というのは「ここまで考えるのか」と思いました。攻撃者は防御の盲点を探すのが本当にうまいです。

「latestじゃないから安全」は通用しない

image_0020.svg

記事で特に重要なのはここです。
npmでは、latest タグだけ見て安心してはいけません。package.json^3.0.6 のように指定していると、​その範囲で一番新しいバージョンが入ります。

image_0021.svg

たとえば echarts-for-reactlatest は 3.0.6 のままでも、^3.0.6 を書いているプロジェクトは、次のクリーンインストールで 3.2.7 の悪性版を拾う可能性があります。

これ、地味だけど本当に重要です。
「最新版じゃないから大丈夫」ではなく、​依存範囲の書き方そのものが攻撃面になるわけです。パッケージマネージャーの仕様が、そのまま攻撃者の武器になる好例だと思います。

image_0022.svg

何が特に危険だったのか

image_0023.svg

この攻撃の厄介さは、単なる情報窃取ではなく、​複数の再感染・再実行ポイントを持っていたことです。

image_0024.png

つまり、1つ潰しても別経路で生き残る設計です。
セキュリティの世界では「再現性のある除去」が大事ですが、これはその逆をやってきます。
個人的には、​**“感染”というより“居座り”**に近い印象を受けました。

image_0025.jpg

どう備えるべきか

元記事では、対策の一例として Package Manager Guard(pmg)が紹介されています。
これは、​インストール時に脅威情報を照合して、危ないパッケージを止めるためのオープンソースの仕組みです。
特に、公開直後の不審なバージョンを一定期間ブロックする「cooldown」機能は、今回のような短時間の大量公開には相性がよさそうです。

image_0026.png

現実的には、次のような対策が大事だと思います。

image_0027.png

率直な感想

image_0028.png

正直、今回の攻撃はかなり完成度が高いです。
「盗む」「隠す」「残る」「また動く」の全部が入っています。しかも、npm、GitHub、CI/CD、AIツール、ローカル常駐までつなげている。攻撃者の視野が広いというより、​開発環境全体を1つの侵入面として見ている感じです。

image_0029.svg

一方で、こういう事件が起きるたびに思うのは、オープンソースの便利さは本当に強力だけれど、そのぶん信頼の連鎖が非常に細いということです。
1つのアカウント侵害が、何十万、何百万という環境に広がる可能性がある。これが supply chain attack の怖さで、しかも今回はその教科書みたいな事例です。

開発者としては「自分のプロジェクトは大丈夫」と思いがちですが、実際には依存している“誰かの誰か”の事故で巻き込まれます。
だからこそ、パッケージ導入をただの便利作業として扱わず、​供給元を信頼するコストまで含めて考える必要があるのだと思います。

image_0030.webp


image_0031.webp

参考: Mini Shai-Hulud Strikes Again: 317 npm Packages Compromised

同じ著者の記事