【超初心者向け】Node.js & npm/axiosを悪用したサプライチェーン攻撃について

昨日、npmで非常によく利用されているaxiosが乗っ取られたというポストを見た。

最近はAIでゴリゴリ開発する人が増えているが、AIに言われるがまま推奨されたソフトをインストールしたり、適当なサイトを読み込ませたりしていると、いつの間にか重要情報が引き抜かれていたり、ウイルスに感染したりするというリスクがある。

なんとなく危ないのは理解できるが・・・
そもそも、Node.js とか npm とかに触れてこず、いきなり開発を始めてしまった人は、概要も対策もわからない。
かくいう筆者も、Node.jsはほとんど触ったことがなく、お恥ずかしながらあまりフォローできていない。

しかしながら、今後もAIを駆使してガンガン開発を進めるのであれば、理解があやふやなままにしておくのはよろしくない。そこで本記事では、Node.jsやnpmとは何ぞや? という超初歩的なところから、今回の問題点までなるべく優しく纏めてみた。

自分の備忘録的な要素が強いが、同じようなレベルの人の参考になれば幸いである。

目次

Node.jsとは?

Node.jsはJavaScriptをサーバー側でも動かせる仕組みである。
あくまで仕組みであって、PHPやRubyなどのプログラミング言語とは異なる。

JavaScriptというと、少なくとも筆者の場合は、

  • ボタンを押したら色が変わる
  • メニューが開閉する
  • スライドショーが動く

みたいに、Webページの見た目や動きに関わるものというイメージが強い。
実際、JavaScriptを使って多くのWebアプリを作ってきたし。

では、サーバー側でJavaScriptを動かすとはどういうことか?
これはつまり、以下のような裏側の処理をJavaScriptで行うということ。

  • サーバーを立てる
  • ファイルを読む
  • データベースとやり取りする
  • APIを作る
  • 開発ツールを動かす

より具体的に対比すると、

ブラウザ側のJavaScriptサーバー側のJavaScript
主に画面にあるものを扱う画面は直接触らない
・HTMLを書き換える
・ボタンのクリックを受け取る
・入力フォームをチェックする
・アニメーションを動かす
リクエストを受け取る
データベースにアクセスする
JSONを返す
ファイルを読み書きする
APIと通信する
document
window
querySelector
addEventListener
http
fs
process

ただ異なるのは役割や道具であって、JavaScriptの基本文法そのものは同じ。

  • 変数や関数の定義の仕方
  • ifforの使い方
  • 配列やオブジェクトの扱い方

こうした部分は、ブラウザ側でもサーバー側でも共通。
同じ言語が使えるので、初心者でも取っつきやすいのがNode.jsというわけ。
(筆者は、PHPで動くWordPressやECCUBEを使ってきた関係上、Node.jsを使う機会がなかったが・・・)

npmとは?

次に出てくるのはnpm。
Claude CodeやCodexを導入するときも、Node.jsを入れた後にnpmを使う。

npmはざっくりいうと、JavaScriptやNode.jsの部品を入れて管理する仕組みのこと。
npm(https://www.npmjs.com/)には、便利な機能をひとまとめにした部品(ライブラリやツール)が置かれている。これらを利用すれば、自分でわざわざ複雑な機能を実装する必要がなくなるのである。

ブラウザでJavaScriptを使うときも、ネット上のJavaScriptファイル(Swiper.jsなど)を直接読み込むCDNという方法が使われる。<script src="https://example.com/swiper.js"></script> と書くだけで特定の機能を利用でき、あれと少し似ている。

ただCDNは、外にある完成品をその場で借りて使う方式であるのに対し、npmは部品を入れて管理する仕組みという点で異なる。

npmの使い方

Codexを導入するときはnpm install -g @openai/codex
Claude Codeを導入するときはnpm install -g @anthropic-ai/claude-code

のように、npm install XXXとコマンド打てば、希望の部品を自分のPCや開発環境にインストールできる。

さらにnpmでは、導入だけでなくバージョンの管理もできるので、プロジェクトごとに必要なものをそろえられたり、他の人と同じ状態にしやすくしたりできる。Gitのバージョン管理に、ちょっと似ている。

axiosとは?

さて、Node.jsとnpmについて仕組みがなんとなくわかったところで、今回の騒動になったaxiosについて。

axiosは、Web通信をするための超有名なJavaScriptライブラリで、先ほどのnpmを使ってインストールできる。axiosを使うと、

  • APIからデータを取る
  • フォーム送信のリクエストを送る
  • サーバーとJSONでやり取りする

といったことが簡単にできるようになる。

axios乗っ取りとサプライチェーン攻撃について

今回は、この人気ライブラリのaxiosが乗っ取られ、特定バージョンに悪意ある依存が混入し、インストール時にRATを取得・実行する仕組みが入れられたとのこと。

RATは Remote Access Trojan の略で、外部からPCを操作できるようにする悪質なソフト。

問題となったバージョンはaxios@1.14.1axios@0.30.4 の2つ。
そして、それらと依存関係があるplain-crypto-js

では、これらのバージョンをインストールしていなければ安全なのか?
というと、そうでもないのがややこしいところ。

axiosは非常に広く使われているため、直接使っていなくても依存関係経由で影響を受ける可能性があるのだ。

依存関係とは?

たとえば、あるライブラリAを入れたとする。
でもそのライブラリAを動かすためには、内部でライブラリBやCを利用する必要がある。

このように、ある部品が別の部品に頼っている関係を依存関係という。

つまり、表面上は今回のaxiosとは異なるパッケージを入れたつもりでも、裏ではaxiosも入って動いていることがある。

これが便利な反面弱いところでもあり、サプライチェーン攻撃と呼ばれる注意すべきポイントである。

サプライチェーン攻撃とは、ソフトウェアの開発・配布・更新の流れのどこかを汚染し、利用者に悪意あるコードを届ける攻撃のこと。今回のaxiosの件は、その中でも依存関係を悪用したタイプの事例。

感染したかどうかの確認

以下のコマンドを使うことで、今開いているプロジェクト(フォルダ)に、今回問題となったソフトが含まれていないかを確認できる。

  • npm list axios
  • npm list plain-crypto-js
  • npm list -g axios
  • npm list -g plain-crypto-js

listは状態を確認するコマンド。
これの結果 (empty) と表示されれば、少なくともその場所(自分のプロジェクトや共通領域)にはパッケージが存在しないことがわかる。

しかし、ここで (empty) だったからといって、絶対に安心とは言えない。

今回のマルウェア(RATと呼ばれる遠隔操作ウイルス)は、パッケージがインストールされた直後に、PC本体(OS自体)の奥深くにウイルスをコピーして潜伏させるという悪質な仕組みを持っている。

つまり、過去に一瞬でもインストールしてしまうと、後からパッケージを削除して(empty)になった状態でも、ウイルス自体はすでにPC内で動いている可能性がある。

そのため、安全を確認するには、自分のPCのOSに応じた怪しいファイル(Windowsであれば%PROGRAMDATA%\wt.exe、macOSであれば/Library/Caches/com.apple.act.mond など)が作成されていないか、直接確認する必要がある。

当面の対策

先程の依存関係の話があり、どのパッケージに問題となったバージョンが入っているか不明なので、しばらくは新しいパッケージを入れないようにするしかない模様。

AIで開発を進めているなら、以下のようなリクエストは拒否したほうが賢明である。

  • npm install
  • npm i
  • npm install -g …
  • npx …

まとめ

Node.js

JavaScriptをサーバー側や開発環境でも動かせるようにしたもの。

npm

JavaScriptやNode.jsのライブラリ、ツールを入れて管理する仕組み。

axios

通信処理でよく使われる有名ライブラリ。
今回一部バージョンに悪意ある依存が混入し、インストール時にRATを取得・実行する仕組みが入れられた。

依存関係

あるライブラリが別のライブラリに頼っている関係。
今回の騒動では、問題のあるaxiosのバージョンが他のライブラリで使われているかもしれない、ということ。

当面の対策

不用意なnpm install は避ける。
安全なバージョンを固定して利用し、感染確認ではnpm listの結果だけで安心しないこと。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次