Islands in the byte stream

Technical notes by a software engineer

npmjs.com で著名ソフトウェアによく似た名前のマルウェアが大量に発見された

Malicious packages in npm. Here’s what to do | Ivan Akulov’s blog

People found malicious packages in npm that work like real ones, are named similarly real ones, but collect and send your process environment to a third-party server when you install them

訳:

悪意のあるパッケージがnpmで発見された。それらは、実際のパッケージによく似た名前で同じように動くが、パッケージのインストール時にプロセスの環境変数を外部のサーバに送信する。

発見されたパッケージの一覧は元エントリをどうぞ。このようなマルウェアである偽パッケージの一例をあげると、 babelcli, d3.js, ffmepg, jquery.js, mysql.js, openssl.js などです。これらのパッケージが依存関係にある場合、tokenなどの秘匿値を再生成すべきとのこと。

package.jsonに書いた直接の依存関係だけでなく、 依存ツリーのすべて を調べる必要があります。つまり、 あなただけでなく依存ツリー中の誰かがミスって偽パッケージを使っただけであなたの環境が攻撃対象になる ということです。依存関係は npm ls などで調べられます。

ライブラリ開発者としては、 scoped packages を使うのがよさそうだと元エントリでは述べています。

所感

オンラインでコードを配布・使用する以上、どんなパッケージリポジトリでもマルウェアを配布することはできます。つまり、npmjs.com (npm) だけの問題ではありません。

一方で、ある機能を実現するための別のパッケージが非常に沢山あります。たとえば、 zstdのnode binding だけでもパッと見て4つくらいあります。これは、npmのユーザー(=JSの開発者)が他の言語にくらべて桁違いに多いため、車輪の再発明が頻繁におきるからではないかと想像しています。

また、しばしば同じライブラリに対応する複数の配布パッケージがあります。一例をあげると、lodash は単体で lodash (commonjs modules版) と lodash-es (ES modules版)という配布パッケージがあり、またlodashの提供する関数ごとに配布パッケージが提供されています (たとえば lodash.merge packageなど)。このような状況だと、たとえば react-es というパッケージを作って「ReactのES modules版です!」というdescriptionを設定すると、いかにもそれっぽく見せかけられます。つまり、著名ソフトウェアに便乗してマルウェアを配布することが簡単にできてしまいます。

この問題はなかなか難しくて対処療法ではない本質的な改善をどうしたらいいのかは分からないのですが、さしあたり自分の管理するライブラリに関しては、 scoped packages にして配布するしかないかなという気がします。

追記

npmjs.org の配布パッケージの中身をウェブで見ることができない、というのもnpmの問題のひとつと言えるかもしれません。

…できないですよね? 例:

たとえば metacpan.org は配布パッケージの中身をウェブで確認できます。例:

rubygems.org も配布パッケージの中身をウェブでは確認できませんね。例:

追記(2)

  • 元エントリに確認用ワンライナがあり、今回発見された分に関していえば確認することはできます
    • 元エントリが更新される可能性を考慮してここには引用しません
  • 公式見解でました: The npm Blog — `crossenv` malware on the npm registry