ヤルキデナイズド

Unclassified Articles on Software and IT

npm パッケージの unpublish に関するゴタゴタの大まかなまとめ

(最終更新:3月24日16:50ごろ)

事件の流れ

何が問題だったのか

npm の仕様

  • パッケージの所有者がパッケージを unpublish できるようになっていること
    • メジャーなパッケージマネージャの多くは unpublish に相当する操作をユーザーに提供しない
    • 代わりとして unlist (NuGet)yank (Cargo) といった操作を提供することがある
    • unlist/yank されたパッケージはリポジトリの一覧には表示されなくなるが、依存解決中にそのパッケージをダウンロードすることは可能
    • 本当の緊急時のみリポジトリ管理者の手でパッケージが削除されることはある
  • unpublish されたパッケージのネームスペースを他人が乗っ取れるようになっていること
    • 同一バージョンの再 publish はできないものの、別のバージョンで悪意のあるコードを publish すると依存元パッケージを攻撃できる可能性がある

人的要因

  • 代理人と作者のやりとりにおいてお互いの態度がよろしくなかったこと
  • 法務関係の事態とはいえ、 npm 運営が作者の許可を得ずパッケージを unpublish したパッケージの所有権を移し替えたこと
    • npm のパッケージ名に関する紛争解決ポリシーによれば、ユーザー間で問題が解決できなければ運営が調停するとされる
  • 抗議のためとはいえ、作者が多数のパッケージを一度に unpublish したこと
    • 混乱を招くことは承知していたようだが、 left-pad に依存する babel まで壊れることは予測していなかったと思う
  • npm 運営が社内の合意もおろそかに unpublish の取り消しを実行したこと

関連記事

余談:

  • 一般的なパッケージマネージャのつくりに興味がある人にはこの記事がおすすめ。 Go のパッケージマネージャを新規設計する視点から問題領域などを分析してる:So you want to write a package manager — Medium
    • “パッケージ管理は厄介な領域だ。本当に厄介だ。表面上は純粋に技術的に解決可能と見える。そう考えて取り組んだ者は皆、避けがたい次なる結論に至る:ソフトウェアはおそろしい。人々はおそろしい。シナリオは無数にあり、何ひとつまともには動かない。証明可能なことに、何ひとつまともには動かない。人生とは逆巻くカオスとエントロピーの渦の中の無意味な摂動。”

感想

  • JS 界隈に単機能モジュールを多数組み合わせて使う風潮があるため被害が広がったなという感じ
  • unpublish 操作はユーザーに開放しないほうがいいと思う
    • npm は他のパッケージリポジトリと比べてパッケージ数が桁違いに多いため、 npm 社としては unpublish を依頼制にしたくないんだろうけど
    • パッケージ作者に無断で管理者がパッケージを削除することは、法に反するコンテンツを含む場合などはやむを得ないだろうが、今回のケースは微妙
  • Objective-C/Swift のパッケージマネージャ CocoaPods は Pods ディレクトリ(依存先パッケージのソースコードを集約するディレクトリ)をバージョン管理することを推奨している。こうすると万が一依存先パッケージが削除されても影響を受けない。デメリットもあるがよいプラクティスだと思う

ブコメ返信

id:teppeis

今回のケースではunpublishが禁止されても乗っ取りは防げるけどエコシステムの破壊は免れなかった。iOS詳しく知らないけどCocoaPodsはプラットフォーム限定できてビルド不要という違いがあるのでは。

ユーザーによる unpublish が禁止されていたとしたら、管理者権限での kik の unpublish によって依存関係が壊れることこそ免れないものの、その他多数のパッケージの突然の unpublish は為されず、被害は比較的小さく済んだはず。

CocoaPods で Pods ディレクトリのバージョン管理が現実的なのは、 Pods ディレクトリにパッケージのソースコードだけが保存されるから。ビルドは必要だが生成物は別のディレクトリに出力される。

ソースコードとプラットフォーム依存のバイナリを同じディレクトリに保存する npm や Ruby の Bundler などでは真似できなそう。