2021年12月13日
中身のないnpmパッケージ「-」が70万回以上ダウンロードされる— その理由とは
本記事は、原著者の許諾のもとに翻訳・掲載しております。
名前が1文字の「-」という謎めいたnpmパッケージは、2020年にレジストリで公開されて以来、70万回以上ダウンロードされています。
さらに、このパッケージには有効なコードが含まれていません。では、一体なぜこれほど多くダウンロードされているのでしょうか?
npmパッケージ「-」の中身
「-」というnpmパッケージは、2020年初めにnpmレジストリで公開されてから、約72万回もダウンロードされてきました。
パッケージのバージョンは0.0.1のみで、ファイルは3つです。
tar tvf 0.0.1/--0.0.1.tgz
package/dist/index.js
package/package.json
package/README.md
これらのファイルは主にマニフェスト(package.json)とindex.jsで、特に面白い点はなく、スケルトンコードが書かれているだけです。
マニフェストはdevDependenciesでパッケージを導入し、「ts-node」コンポーネントのコマンドを呼び出していますが、それ以上のことは書かれていません。今のところ、実質的にはデッドコードです。 「-」のindex.jsファイルとマニフェストファイル(package.json)(BleepingComputer)
50以上のパッケージが「-」を使用
さらに不思議なこともあります。
無用同然のパッケージ「-」は50以上のnpmパッケージで、明確な説明なしに依存関係として使用されているのです。 56のパッケージがnpmパッケージ「-」を使用(npmjs.org)
しかし、ほとんどの依存関係は週に数十回しかダウンロードされていません。
それでは、なぜ「-」は約72万回もダウンロードされているのでしょうか?
おそらく、このパッケージが呼び出される理由は、npmコマンドをターミナルから実行する際のタイプミスでしょう。
例えば、「somepackage」というnpmパッケージをインストールするときは、以下を実行する必要があります。
npm i somepackage
フラグを指定するときに、例えば次のようなミスをしたとします。
npm i - someFlag somepackage
「-」とsomeFlagの間にスペースがあります。そのため、「-」という名前のパッケージが存在する場合、npm によってそのパッケージがインストールされます。
つまり、このパッケージが何十万回もダウンロードされたのは、開発者のタイプミスによるものと考えられます。
同様に、コマンドラインを通じてpackage.jsonに依存関係を追加するとき、誤って「-」が混入することは簡単に予想できます。
BleepingComputerは、テストで「somepackage」と「axsharma」をnpmからダウンロードするため、以下のコマンドを実行しました。
ただし、意図的にタイプミスして、「--save」フラグの前に余計な「-」を入れました。
npm install somepackage axsharma - --save
予想通り、実行後のpackage-lock.jsonファイルとnode_modules/フォルダには「-」パッケージが含まれています。このように現実の依存関係にも「-」が混入する可能性があります。
生成されたnode_modulesフォルダとpackage-lock.jsonファイルには「-」パッケージが含まれる(BleepingComputer)
パッケージのREADME.mdファイルとnpmページは、いずれも「-」がスクリプトによって生成されたことを示しています。
「-」のREADMEファイル(BleepingComputer)
「-」を作成した開発者のインタビュー
BleepingComputerはパッケージの作成者Dmitry Parzhitsky氏を取材し、このパッケージを作成した理由などを質問しました。以下はその回答です。
「最初に言っておくと、このパッケージによって、誰かに害を与えるつもりは全くありません」とParzhitsky氏は語りました。パッケージは作成当時のnpmの命名規則に完全に準拠しており、テストとして作成されたものだと強く主張したのです。
「もともとパッケージを公開した理由は、『-』が命名規則に沿った有効なパッケージであるかを確認することでした。不思議なことですが、この名前は有効です。例えば『--』という名前のパッケージも公開できます」と彼は続けました。
Parzhitsky氏は、ダウンロード回数が異様に多い理由について、おそらく開発者のタイプミスだろうというBleepingComputerの仮説に同意しています。
さらに彼は、今のところ「-」には何の機能もないが、誤ってパッケージをインストールしたときにエラーメッセージを返すように修正するという意向を明確にしました。
Parzhitsky氏は「このパッケージの挙動は奇妙で、いくらか危険かもしれません。ですから、『-』や『g』、『D』などのパッケージを誤ってインストールしたと疑われる場合に警告を返す機能を導入する予定です」と述べて、私たちとのメールによるインタビューを締めくくりました。 GitHubのイシューでは開発者が警告を導入する計画が公表されている
今のところ、「-」が悪意あるプログラムだと示すものは何もありませんが、開発者は誤って「-」などのパッケージをビルドに混入させないよう注意すべきだといえます。
その他、1文字の名前のパッケージや、npmコマンドに似た名前のパッケージとしては、i、g、install、D、sなどが挙げられます。
つまり、誤って「npm i somePackage」ではなく「npm i i somePackage」とタイプした場合、somePackageに加えてiというパッケージもインストールされます。
「本当に問題なのは、これらのパッケージが気づかないうちにインストールされることです。誤ってnpm install - g my-packageを実行しても、目的のパッケージはインストールできます」
「後で別の場所からパッケージにアクセスしようとするまで、タイプミスの可能性には気づきません。それまでは『-』と『g』の両方がプロジェクトに混入しています」
「npmはコマンドと同じ名前のコンポーネントを禁止できるはずです(おそらく禁止すべきでしょう)」。Sonatypeのソフトウェア開発者であるMatt Freeland氏は、BleepingComputerに情報を提供した後でこのように語りました。
さらにFreeland氏は、npm install の実行後に、インストールされたパッケージ名がそのままリストアップされず、「3つのパッケージを追加し、8つのパッケージを検査しました」といった簡単な成功メッセージが表示されることを指摘しました。
そして「インストールしたパッケージ名を成功メッセージに記載すれば、開発者が誤りに気づく可能性があります」と続けています。
最近はnpmなどのオープンソースレジストリがマルウェアや害のあるコンテンツであふれる事態が再三にわたり発生しています[1, 2, 3]。
開発者は、ターミナルにnpmコマンドを入力するとき(特にフラグを使用する場合)は、注意を払うべきです。また、自分のパッケージがなぜこのような謎めいたパッケージに依存しているのかを確認するのも良いでしょう。
※2021年8月4日午前7時15分(米国東部時間)更新:BleepingComputerがParzhitsky氏(「-」の開発者)に連絡したのは、本記事が公表されるかなり以前のことです。しかし、詳細な回答が返ってきたのは相当の時間が経ってからで、本記事を公表した後でした。そのため、本記事の一部を更新し、開発者の回答を追加しました。透明性を確保するため、元記事をアーカイブしたコピーをWayback Machineで閲覧できるようにしています。
関連記事:
- NPM fixes private package names leak, serious authorization bug
- Popular 'coa' NPM library hijacked to steal user passwords
- Give the gift of learning a new language with this subscription
- Get unlimited access to 210 top Mac apps for $42 this Black Friday
- Read, edit, and write PDFs with Apple's App of the year
株式会社リクルート プロダクト統括本部 プロダクト開発統括室 グループマネジャー 株式会社ニジボックス デベロップメント室 室長 Node.js 日本ユーザーグループ代表
- Twitter: @yosuke_furukawa
- Github: yosuke-furukawa