12 ポイント 投稿者 GN⁺ 29 일 전 | 2件のコメント | WhatsAppで共有
  • 広く使われているaxios HTTPクライアントの2つの悪性バージョンがnpmに公開され、インストール時にリモートアクセス型トロイの木馬(RAT) を配布した
  • 攻撃者はメンテナーアカウントの認証情報窃取によってGitHub Actionsを迂回し、手動で悪性パッケージをアップロードした
  • 悪性バージョンには偽の依存関係 plain-crypto-js@4.2.1 が含まれており、postinstallスクリプトでRATをインストールして痕跡を削除する
  • RATはmacOS、Windows、Linuxのすべてに感染し、C2サーバー(sfrclak.com:8000)と通信して追加ペイロードをダウンロードする
  • npmとGitHubは迅速に悪性バージョンを削除したが、サプライチェーンセキュリティ強化と認証情報保護の重要性が改めて浮き彫りになった

axios npmサプライチェーン攻撃の概要

  • 2026年3月31日、広く使われているaxios HTTPクライアントライブラリの2つの悪性バージョン(axios@1.14.1axios@0.30.4)がnpmに公開された
  • 攻撃者はaxios主要メンテナーのnpm認証情報を窃取し、GitHub ActionsのCI/CDパイプラインを迂回して手動で悪性パッケージを公開した
  • 2つのバージョンはいずれも**plain-crypto-js@4.2.1** という偽の依存関係を挿入しており、このパッケージはpostinstallスクリプトを通じてリモートアクセス型トロイの木馬(RAT) をインストールする
  • RATはmacOS、Windows、Linuxのすべてを対象とし、C2(Command and Control)サーバー(sfrclak.com:8000)と通信して第2段階ペイロードを取得する
  • インストール後に悪性コードと痕跡を削除し、クリーンなpackage.jsonに置き換えてフォレンジック検知を回避する

攻撃タイムライン

  • 3月30日 05:57 UTC: plain-crypto-js@4.2.0(正常版)公開
  • 3月30日 23:59 UTC: plain-crypto-js@4.2.1(悪性版)公開、postinstallフックを追加
  • 3月31日 00:21 UTC: axios@1.14.1公開、悪性依存関係を挿入
  • 3月31日 01:00 UTC: axios@0.30.4公開、同じ悪性依存関係を挿入
  • 3月31日 03:15 UTC: npmが2つの悪性バージョンを削除
  • 3月31日 04:26 UTC: npmがplain-crypto-jsをセキュリティホルダースタブ(0.0.1-security.0)に置き換え

axios概要

  • axiosはJavaScriptエコシステムで最も広く使われているHTTPクライアントで、Node.jsとブラウザの両方で利用される
  • 週間ダウンロード数は3億回を超え、たった1回の悪性リリースでも広範な被害の可能性がある
  • 一般の開発者はnpm install時に悪性コードのインストールに気付きにくい

攻撃段階

  • 第1段階 — メンテナーアカウントの乗っ取り

    • 攻撃者は**jasonsaayman npmアカウント**を乗っ取り、メールアドレスをifstap@proton.meに変更
    • その後、1.x系と0.x系のリリースブランチの両方に悪性ビルドを公開
    • 正常なリリースはGitHub ActionsのOIDC Trusted Publisherを通じて公開されるが、axios@1.14.1は手動公開でgitHeadとOIDC署名がない
    • 攻撃者は有効期限の長いnpmアクセストークンを利用したとみられる
  • 第2段階 — 悪性依存関係の事前配布

    • plain-crypto-js@4.2.1nrwise@proton.meアカウントから公開された
    • crypto-js偽装し、同一の説明文とリポジトリURLを使用
    • "postinstall": "node setup.js"フックを含み、インストール時に自動実行される
    • 攻撃後にpackage.mdpackage.jsonへ置き換え、証拠削除の準備を行う
  • 第3段階 — axiosへの依存関係挿入

    • plain-crypto-js@^4.2.1ランタイム依存関係として追加
    • コード内では一度もimportされない → ファントム依存関係(phantom dependency)
    • npm install時に自動インストールされ、postinstallスクリプトが実行される

RATドロッパー(setup.js)分析

  • 難読化手法

    • 文字列を配列stq[]に暗号化保存し、_trans_1(XOR)と_trans_2(Base64+逆順)で復号
    • C2 URLはhttp://sfrclak.com:8000/6202033
    • 復号された文字列にはOS識別子(win32darwin)、ファイルパス、シェルコマンドなどが含まれる
  • プラットフォーム別ペイロード

    • macOS

      • AppleScriptを/tmpに書き出してosascriptで実行
      • C2からRATバイナリを取得して/Library/Caches/com.apple.act.mondに保存・実行
      • ファイル名はAppleのシステムデーモンのように偽装されている
    • Windows

      • PowerShellのパスを探索した後、%PROGRAMDATA%\\wt.exeへコピー
      • VBScript経由でC2からPowerShell RATをダウンロードして実行
      • 一時ファイル(.vbs.ps1)は実行後に削除される
    • Linux

      • curl/tmp/ld.pyをダウンロードし、nohup python3で実行
      • /tmp/ld.pyファイルが残る
      • 3つのプラットフォームすべてでpackages.npm.org/product0~2のPOSTボディを使い、正規のnpmトラフィックのように偽装する
  • 自己削除と隠蔽

    • setup.jspackage.jsonを削除
    • package.mdpackage.jsonへ置き換え、正常パッケージに偽装
    • その後はnpm auditや手動レビューでは検知できない
    • ただし、node_modules/plain-crypto-js/の存在自体が感染の証拠となる

StepSecurity Harden-Runnerによる実行検証

  • Harden-RunnerはGitHub Actionsでネットワーク・プロセス・ファイルイベントをリアルタイム記録する
  • axios@1.14.1のインストール時に2回のC2接続(curlnohup)が検知された
    • 1回目の接続はnpm install開始から2秒後に発生
    • 2回目は36秒後で、バックグラウンドプロセスとして継続実行された
  • プロセスツリー分析の結果、nohupプロセスがPID 1(init) に孤児プロセスとして残り、継続実行していることが確認された
  • ファイルイベントログではpackage.jsonが2回上書きされた
    • 1回目: インストール中に悪性版を書き込み
    • 2回目: 36秒後、クリーンなスタブに置き換え

侵害指標(IOC)

  • 悪性npmパッケージ

    • axios@1.14.1 · shasum: 2553649f232204966871cea80a5d0d6adc700ca
    • axios@0.30.4 · shasum: d6f3f62fd3b9f5432f5782b62d8cfd5247d5ee71
    • plain-crypto-js@4.2.1 · shasum: 07d889e2dadce6f3910dcbc253317d28ca61c766
  • ネットワーク

  • ファイルパス

    • macOS: /Library/Caches/com.apple.act.mond
    • Windows: %PROGRAMDATA%\\wt.exe
    • Linux: /tmp/ld.py
  • 攻撃者アカウント

    • jasonsaayman(侵害されたメンテナー)
    • nrwise(攻撃者が作成したアカウント)
  • 安全なバージョン

    • axios@1.14.0(正常)

影響確認と対応手順

  • npm list axiosまたはpackage-lock.json1.14.1 / 0.30.4を確認
  • node_modules/plain-crypto-jsの存在有無を確認
  • OSごとのRATファイルが存在する場合はシステム完全侵害と見なす
  • CI/CDログで該当バージョンのインストール履歴を確認し、すべての秘密鍵・トークンの交換が必要

復旧手順

  1. axiosを安全なバージョン(1.14.0または0.30.3) に固定
  2. plain-crypto-jsフォルダを削除後、npm install --ignore-scriptsで再インストール
  3. RATの痕跡が見つかった場合はシステムを再構築
  4. すべての認証情報(AWS、SSH、CI/CDなど)をローテーション
  5. CI/CDパイプラインを点検し、秘密鍵を交換
  6. 自動ビルド時は--ignore-scriptsオプションを使用
  7. C2ドメイン/IPをファイアウォールまたは/etc/hostsで遮断

StepSecurity Enterprise機能

  • Harden-Runner

    • GitHub Actionsでネットワーク送信ホワイトリストを適用
    • 異常トラフィックを遮断し、ログを記録
    • sfrclak.com:8000への接続を事前に遮断可能
  • Dev Machine Guard

    • 開発者PCでインストールされたnpmパッケージをリアルタイム監視
    • axios@1.14.10.30.4がインストールされた端末を即時検知
  • npm Package Cooldown Check

    • 新規公開パッケージに一時的なインストール禁止期間を適用
    • plain-crypto-js@4.2.1のような迅速な悪性公開を検知可能
  • Compromised Updates Check

    • リアルタイム悪性パッケージDBに基づいてPRマージをブロック
    • axios@1.14.1plain-crypto-js@4.2.1を即時登録
  • Package Search

    • 組織全体のPRとリポジトリから特定パッケージの導入箇所を検索
    • 影響範囲(リポジトリ、チーム、PR)を即時把握
  • AI Package Analyst

    • npmレジストリをリアルタイム監視し、振る舞いベースの悪性検知を実施
    • 2つの悪性バージョンはいずれも公開後数分以内に検知
  • Threat Center Alert

    • 攻撃概要、IOC、対応手順を含む脅威インテリジェンスアラートを提供
    • SIEM連携によってリアルタイム可視性を確保

謝辞

  • axiosメンテナーとコミュニティはGitHub issue #10604を通じて迅速に対応した
  • GitHubは侵害されたアカウントを停止し、npmは悪性バージョンの削除とセキュリティホルダー適用を行った
  • メンテナー・GitHub・npmの連携対応により、世界中の開発者被害を最小化した

2件のコメント

 
chanapple 29 일 전

この規模のパッケージが侵害されるなんて考えたこともなかったですが、axiosは想像以上ですね。

 
GN⁺ 29 일 전
Hacker Newsの意見
  • npm、bun、pnpm、uv はいずれも パッケージの最小リリース期間設定 をサポートするようになった
    私は ~/.npmrcignore-scripts=true を追加しているが、この設定だけでも脆弱性を緩和できた
    bun と pnpm はデフォルトで lifecycle スクリプトを実行しない
    各パッケージマネージャーごとの設定例は次のとおり:

    • uv: exclude-newer = "7 days"
    • npm: min-release-age=7
    • pnpm: minimum-release-age=10080
    • bun: minimumReleaseAge = 604800
      興味深いことに、それぞれ 時間単位が異なる
      LLM エージェントを使っている場合、この設定によって失敗が発生する可能性があるため、AGENTS.mdCLAUDE.md に関連する指示を追加する必要がある
    • 「時間単位が全部違うなんて」という発言に対して、「JavaScript を使うのは初日か?」という冗談が付いた
    • pnpm がこの機能を 最初に導入 した。npm は 11.10.0 以上でのみ対応しており、2026年2月11日のリリース から利用可能
    • 設定ファイルでは単位を明示したほうがよいという意見もあった。たとえば timeout ではなく timeoutMinutes のように
    • npm は コメントをサポートしていない可能性があるmin-release-age=7 # days が実際には適用されないかもしれない
    • yarn berry の場合は ~/.yarnrc.ymlnpmMinimalAgeGate: "3d" と設定できる
  • Axios が サプライチェーン攻撃 にさらされたというニュースに衝撃を受けた
    Axios 自体には悪意あるコードは含まれていなかったが、plain-crypto-js@4.2.1 という偽の依存関係を注入し、RAT(リモートアクセス型トロイの木馬) をインストールする postinstall スクリプトを実行していた
    pnpm や bun のように postinstall スクリプトを手動承認する必要があるユーザーにとっては、不幸中の幸いと言える

    • Node.js に fetch が標準搭載されたのは v18 以降 で、安定化したのは v21 からだった。Axios はそれよりずっと前から存在しており、多くのフレームワークやチュートリアルに含まれているため、今なお広く使われている
    • 「pnpm/bun ユーザーは安全だ」という話に対して、「では旧バージョンでは承認していた可能性が高いのでは?」という疑問が出た
    • pnpm が 下位依存関係の postinstall もブロックするのか 気になるという質問も出た
  • パッケージマネージャーは 失敗した実験 だという主張
    SQLite のように単一の .c ファイルで構成された高品質な C ライブラリもあり、こうした方式なら transitive dependency の問題を避けられる
    攻撃対象領域の大半はこうした間接依存から生じている

    • パッケージマネージャーは今や言語普及の必須要素になっている。問題は 品質管理の欠如と報酬構造 にある
      OpenSSL ですらコード品質の問題から 再実装が進められており、JS は標準ライブラリの拡張が難しいため ポリフィルの乱立 が深刻だ
    • 「少し余計に努力が必要な解決策はコミュニティに受け入れられないだろう」という意見もあった
      その代わり、npm のようなレジストリ側で 品質基準を強化し、責任あるメンテナーだけを登録できるようにすべき という提案が出た
    • Web 開発では攻撃対象領域がはるかに広い。手動コピー方式では更新追跡が難しいため、パッケージマネージャーの通知機能 は依然として有用だ
    • NPM だけが特に サプライチェーン攻撃が深刻なエコシステム だという指摘もあった
    • Rust は C より安全で、多くの crate は 高品質 なのだから、C ライブラリ中心の主張は誇張だという反論もあった
  • 今日はどの npm パッケージがやられたんだ?」という自嘲気味のあいさつで一日を始める、という冗談が出た

  • Linux ユーザーなら bwrap を使って npm、pip、cargo、gradle などあらゆるビルドロジックを サンドボックス化 すべきだという勧め
    bwrap は Docker のような隔離環境を提供するが、イメージは不要。Flatpak も同じ技術基盤に基づいている
    サーバー配備時には コンテナハードニング が重要で、CI/CD 環境を信頼しない領域として扱うことが核心だ
    AI 実行時にも同じサンドボックスを使うとよい

    • ただし、この方法は postinstall 攻撃にしか有効ではない という指摘があった。コード内で require するだけでも実行されうるためだ
    • Docker ベースの個人向けサンドボックス amazing-sandbox を作った人もいた
    • drop という bwrap より高水準のツール も勧められていた
    • firejail のほうが 柔軟なセキュリティサンドボックス だという意見もあった
    • SSH ソケットフォワーディングは個人鍵へのアクセスを許してしまうため セキュリティ上の利点がなく、パスワード保護された鍵を使うほうがよいという指摘もあった
  • 依存関係の問題を何度も見ていると、Rust エコシステムもいつか同じことを経験するのではないかと心配 になる
    標準ライブラリを肥大化させるのは難しいが、信頼できるパッケージ品質保証の仕組み は必要だ

    • 大規模パッケージ(Axios など)は、複数の MFA 承認者が公開を承認 すべきだという提案があった
    • 検証済み依存関係を 商用で提供するサービス が現れるだろうという予測もあった
    • 別の提案として、依存関係のテストを直接コピーしてコードベースに含め、自前のコードレビュー手順 を通すやり方も挙げられた
      AI のおかげでこうした追加作業が可能になり、実際は昔からそうすべきだったという反省もあった
  • NPM サプライチェーン攻撃への露出を最小限にするための 重要な実践項目

    • Yarn の zero-installs モード を使う
    • postinstall スクリプトを無効化する、または実行前に確認する
    • 開発中にサードパーティコードが実行される場合は VM/コンテナ内でのみ実行 する
    • パッケージ追加時は 人気度はプラス、最近のコミットはマイナス要因 と見なし、コードと変更履歴を直接レビューする
    • 依存関係ツリー全体を検証し、新しい開発者が追加されるたびに信頼性を再評価すべきだ
    • lockfile と --frozen-lockfile オプションだけでも十分守られるという意見もあった
    • 「自分はただ 問題の多いスタックを避ける」という、単純だが強力な哲学を持つ人もいた
  • 「こうした攻撃を完全に避けるにはどうすればいいのか?」という問いに対し、
    Qubes OS に移行 してパスワードマネージャーとビルド環境を完全に分離したいという意見が出た

    • あるチームは NPM 関連の作業を Apple コンテナ の中でのみ行っており、Python と Rust も同じ方式へ移行する計画だという
      これはまるで 化学実験室の保護具(PPE) のように、開発環境でも隔離と保護が必要だというたとえが使われていた
      pip もすでに virtualenv の外へのインストールを防ぎ始めており、今後はパッケージマネージャーが サンドボックス外での実行を拒否するオプション を提供してほしいという期待もあった
    • ある人は そもそも Node.js/npm をシステムにインストールしない と言っていた。これまで本当に必要な場面を見たことがないという
  • pnpm と bun は現在デフォルトで postinstall スクリプトを無視 するが、npm は依然として実行する
    ~/.npmrcignore-scripts=true を設定するのがよい
    npm は今なお 週8,000万ダウンロード を記録している

  • 今回の認証情報流出は LiteLLM の以前のインシデントに由来する可能性が高い と推測されている
    Python や Node.js の利用に不安を感じるが、実際には もっと普遍的な問題 だとも思える

    • 最小リリース期間設定は役に立つものの、依然として 依存関係の更新は怖い という意見が多かった
    • LiteLLM より Trivy のインシデント が根本原因だという主張もあった
    • rootless の一時コンテナ で実行して被害範囲を限定する方法も提案されていた