依存するパッケージは厳選しよう
JS界隈が大騒ぎになった事件だけど、こういった事件自体は完全に防ぐことは不可能だと思う。
今回は依存ライブラリが削除されるだけで済んだけど、 npm install
するだけで ~/.ssh
ディレクトリを zip にしてどこかに送信するような悪質な攻撃であれば、単にCIが止まるどころでなく、世界中のエンジニアの秘密鍵がばらまかれてあちこちのサーバーにssh可能な事態になったわけで、そんな悪質な攻撃を bugfix なマイクロバージョンアップとして公開される事もありえたわけだ。
第三者のパッケージに依存するということは、それだけのリスクを背負い込むということだ。だが、逆に外部のライブラリに依存しないようにすると、生産性が落ちてしまう。 なので、コードを読む、信頼できるメンテナの公開しているパッケージを選ぶなどといった方法で、リスクとメリットのバランスを取って行かないといけない。
信頼できるパッケージを選ぶ手段の一つとして、既に信頼を集めている人やプロジェクトが信頼しているものを信頼するという方法がある。例えば Babel を使うことを選択した場合、 Babel が依存してる全部のパッケージも信頼して自分のマシンにインストールするということを選んだ訳で、なら自分のプロジェクトでも同じパッケージに依存するというのは合理的な選択のはずだ。
さて、今回の問題で驚いたのは、大混乱を招いた left-pad が、ある程度の技術があるプログラマが見たら一目でクソコードだと判断するような代物だったことだ。
len = len - str.length; while (++i < len) { str = ch + str; }
渡された文字列 str に、 ch で指定されたパディング文字を左に追加することで、指定された長さの文字列にする(右寄せする)コードなのだが、「文字列の左側に1文字ずつ追加する」コードがクソなのは多くの言語で共通の認識だろう。実際、事件の後、パフォーマンスを改善するプルリクエストが4件も立て続けに来ている。 https://github.com/azer/left-pad/pulls
問題は、たった17行のコードに、こんなに明らかな問題があるのに、事件が起こるまで誰にも気づかれずに、 Babel を始めとした大量のプロジェクトで利用されていたことだ。 僕は JSer じゃないので憶測だが、この開発者がJS界で超有名人で信頼されていたというよりも、「Babelも使ってるし」といった感じでどんどん依存が広まっていったのでは無いだろうか? Babel の中の人はそこまで考えて依存するライブラリを選んでいただろうか。(Babelよりも先に left-pad に依存していた有名プロジェクトがあったらごめんなさい)
外部のパッケージに依存することには大きなリスクが有ることを認識した上で、それでも利用することで得られるメリットが上回っているか、良く考えよう。
特に多くの人に利用されるOSSプロジェクトでは、そのメリット・デメリットがそのプロジェクトだけでなくコミュニティ全体に「◯◯が使ってるからウチも使おう」という基準で広まることまで考えて、より厳選しよう。
できれば依存するライブラリのコードを読んで、他人におすすめできるコードかどうか確かめ、そうでないならより良い別のライブラリを探すなり、プルリクエストを出すなりしよう。