LoginSignup
384
156

More than 5 years have passed since last update.

セキュリティ インシデント flatmap-stream@0.1.1 と npm-run-all での対応

Last updated at Posted at 2018-11-27

人気のある npm パッケージ event-stream (DL数: 2M/週) が悪意ある攻撃に利用されるというセキュリティ インシデントがありました。

私が管理する npm-run-all (DL数: 440K/週) も間接的に event-stream に依存していたため、インシデントの詳細と私の対応について触れておきます。

何をすべき?

あなたのプロジェクトが event-stream に依存している場合は、この依存を削除し、代替手段を探すと良さそうです。event-stream の作者は、このパッケージをメンテナンスしないと明言しています。ただ、これだけ騒ぎになったので、信用できる誰かが引き継ぐ可能性はあります。 [編集(2018/11/30)] 現在は npm 社がパッケージ管理を引き継いでいます。ただ、リポジトリは凍結されており、今後変更されることはないでしょう。

次に、あなたのプロジェクト上で以下のコマンドを実行し、

npm ls flatmap-stream

flatmap-stream (悪意あるコードを含んでいる) が存在した場合は、これに依存しているパッケージを最新にアップデートしましょう。nodemon, npm-run-all, @vue/cli 等のパッケージが間接的に依存していました。もし、最新にアップデートしても flatmap-stream への依存が消えない場合、原因になっているパッケージを削除し、代替品を探すと良いでしょう。

また、Visual Studio Code のユーザーは、拡張機能が悪意あるコードの影響を受けていないかチェックしましょう。Microsoft が影響を受けている拡張機能について列挙してくれました

何があったか?

攻撃者は巧妙に攻撃を秘匿しながら、copay というビットコイン ウォレットに悪意あるコードを注入し、ビットコインを窃盗しようとしました。どうやら未遂に終わったようです。

時系列を見てみましょう。

2017年10月
event-stream パッケージへの最後の (正常な) コミット。
2018年8月頃
flatmap-stream パッケージが作られた。まだ無害。
8月末
攻撃者が event-stream パッケージへの関与を開始した。event-stream 作者に対してメンテナンスを引き継ぎたい事を知らせ、権限を受け取った。
9月9日
攻撃者が event-stream@3.3.6 を公開。これに flatmap-stream@^0.1.0 への依存が追加された。まだ無害。
9月16日
攻撃者が event-stream@4.0.0 を公開。これから flatmap-stream@^0.1.0 への依存が削除された。メジャーバージョンアップなので、大半のパッケージは 3.x に依存し続ける一方、npm のページ等では最新版の依存関係しか表示しないため、依存を隠蔽する効果がある。
9月26日
copay が依存を更新して event-stream@3.3.6flatmap-stream@0.1.0 に依存した (copay#baab80)。準備完了。
10月5日
攻撃者が悪意あるコードを注入した flatmap-stream@0.1.1 を公開した。
10月23日
Node.js 11 がリリースされた。
10月26日
copay が依存を更新して flatmap-stream@0.1.1 に依存した (copay#9643f1)。注入完了。
10月29日
nodemon パッケージに、Node.js 11 で実行すると「非推奨 API を利用している」というシステム警告が出ると報告があった (nodemon#1442)。特に調査は行われず。
11月19日
event-stream リポジトリに、疑わしいコミットがある事を指摘する Issue が作られた (event-stream#115)。それ以上の調査は行われず。
11月21日
nodemonの非推奨警告の調査から悪意あるコードが再発見され、event-stream リポジトリに詳細を記載した Issue が作られた (event-stream#116)。これに対し、event-stream の作者は既にパッケージの管理権限を手放していることを告げた。
11月27日
Hacker News 等に event-stream#116 が転載され、大騒ぎになった。
flatmap-stream パッケージは npm リポジトリから削除された。
event-stream@3.3.6 は npm リポジトリから削除された。
event-stream パッケージの管理権限を npm 社が一時的に引き取った。
copay 開発メンバーは、悪意あるコードはどのプラットフォームにもデプロイされていなかったと報告した。また、 copay 5.0.2〜5.1.0 の間、悪意あるコードが注入されていたことを報告した。被害の詳細は調査中とのこと。

こうしてみると、攻撃者が時間をかけて慎重に行動していたことが窺えます。悪意あるコードが Node.js 11 で非推奨になった API を利用していたのは幸運だったでしょう。

なお、npm-run-all パッケージには11月22日に報告があり、私は24日土曜日に事態を認識して対処しました。現在の最新版には event-stream/flatmap-stream への依存はありません。

どんな攻撃だった?

非常に巧妙な狙撃のような攻撃でした。

攻撃コードは暗号化されており、環境変数 npm_package_description に格納された文字列をキーに復号してから実行するようになっていました。環境変数 npm_package_description というのは、npm-scripts 実行時に npm が自動的に設定する環境変数で、内容は package.jsondescription プロパティの値となります。つまり、パッケージの概要説明です。

パッケージの説明文はパッケージ毎に異なるので、ほとんどの場合は攻撃が失敗し、何もしません。反面、私たちが悪意あるコードを発見しても、攻撃対象のパッケージがどれか分からなければ攻撃コードを復号できず、解読できません。

そして、説明文が "A Secure Bitcoin Wallet" だったときだけ復号に成功し、ビットコインの窃盗という攻撃行動を行います。

狙撃です。

良いニュースは、大半の人はこの攻撃の影響を受けなかったことです。

今後の対策は...?

まず、私たち npm パッケージの開発者は、今回のインシデントを教訓としなければなりません。信用できると確認できない人物にコミット権限やリリース権限を与えないよう。

間接依存しているライブラリに攻撃コードが注入されるのでは、私たち開発者はたまったものではありません。これは氷山の一角なのでは? という不安はどうしてもついてまわります。
npm 社からはまだコメントが出ていませんが、不安を抑えるためにも、なんらかの仕組みが必要だと思います。審査強化という方向に行くのか、パッケージにパーミッションを持たせる方向に行くのか。

発表を待ちましょう。 [編集(2018/11/30)]: npm より The npm Blog — Details about the event-stream incident との記事が発表されました。特に追加の施策はなさそうです。

384
156
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
384
156