Japan
サイト内の現在位置
プログラミング言語のパッケージ管理ツールに潜む危険性
NECセキュリティブログ2021年12月17日
NECサイバーセキュリティ戦略本部 セキュリティ技術センター インテリジェンスチームの郡司です。今週のセキュリティブログでは、プログラミング言語のパッケージ管理ツールに潜む危険性に関する話題をお届けします。
はじめに
最近のプログラミング言語にはたいてい「パッケージ管理ツール(およびパッケージリポジトリサービス)」があります。自分が作成したライブラリをパッケージという形にまとめてリポジトリに公開したり、逆に他人が作成したライブラリをリポジトリからパッケージとして追加したりといったことが簡単にできるプラットフォームが提供されています。たとえばプログラミング言語PythonではPyPI[1] 、Node.jsではnpm
[2]、RubyではRubyGems
[3]などです。自分が欲しいと思っている機能を誰かがすでに実装してパッケージとして公開しているのであれば、機能を一から開発しなくても、誰かが作ったパッケージを自分の環境に追加するだけで欲しい機能を実現できます。多くのプログラマの方がこうしたパッケージ管理ツールを日常的に利用していることと思います。
ところがこうしたパッケージ管理ツールは便利な反面、中には悪意を持ったパッケージが公開されていることもあります。今回の記事ではそうしたパッケージ管理ツールに潜む危険性について取り上げてみたいと思います。
悪意のあるパッケージが公開される3つのパターン
最近で話題になった悪意のあるパッケージに関する記事を二つご紹介します。一つは、アメリカのサイバーセキュリティ企業であるRecorded Future社が11月5日に公開した記事[4]で、Node.jsのnpmで非常によく使われている2つのパッケージ「coa」「rc」に悪意のあるコードが混入していたとのことでした。もう一つは、イスラエルのソフトウェア企業であるJFrog社のセキュリティ調査チームが11月18日に公開したブログ記事
[5]で、PythonのPyPIリポジトリにおいて悪意のあるコードを含んだ11個のパッケージが発見されたとのことでした。
両記事によると、悪意のあるコードの挙動としてはクレデンシャル情報(認証に使われる情報)などの秘密情報の窃取、暗号通貨のマイニングをさせられるなどのリソース搾取、DDoS攻撃の踏み台などに利用するためのC&Cサーバ(攻撃指令サーバ)との接続などを行うものなどがあるそうです。
こうした悪意のあるコードを含んだパッケージが公開されているものとしては、主に3つのパターンに分類できます。まず一つ目は何らかの手段で既存のパッケージの開発者のアカウントを乗っ取り、パッケージに不正なコードを混入するというパターンです。先ほどご紹介した記事[4]によると、Node.jsの「coa」「rc」という二つのnpmパッケージの開発者のアカウントが乗っ取られ、パッケージに悪意のあるコードを埋め込まれてしまったとのことでした。
二つ目は表面的には有用なパッケージのように装って公開されているものの、悪意を持ったコードを隠し持っているというパターンです。先ほどご紹介した記事[5]によると、JFrog社では定期的にパッケージリポジトリサービスを監視して、悪意のあるパッケージがないかどうかをチェックしているそうです。しかし、ネットワークベースのチェック(実際に動作させてみて不正な通信がないかどうかを確認すること)を回避するために、悪意のある通信を正当な通信のように偽装するために様々な手法が用いられていることが紹介されています。またパッケージの名称としては「便利そうなパッケージ名」を付けてインストールを誘ったり、有名なパッケージと似たような名前を付けてタイプミス等によって誤ってインストールされることを狙ったりするようです。
三つ目はセキュリティ研究者のAlex Birsan氏が実証を行った「依存関係かく乱攻撃(dependency confusion attacks)」[6]と呼ばれるパターンです。これは、リポジトリ機能の仕様を逆手に取った攻撃です。企業などでは様々な理由で外部に公開したくないパッケージを企業内のプライベートリポジトリに格納して利用していることがあります。この場合、非公開にしたいパッケージ名と同じ名前のパッケージが公開リポジトリにある場合、公開リポジトリのほうのパッケージを取ってきてしまうことがあるようです。そうしたリポジトリ機能の仕様を狙って、企業がプライベートリポジトリで使いそうな名前のパッケージが大量に公開リポジトリに登録され続けているとのことです
[7]。
防御策
それでは、パッケージに対する上記の攻撃からどのように防御すればよいかを考察します。なお、パッケージに対する攻撃手法は上記で挙げたものが全てではありません。以下の対策をすれば絶対に安全というものではないことには注意が必要です。
まずは前述の一つ目のパターンであるパッケージ開発者のアカウント乗っ取りの対策です。これは他のサービスにおけるアカウント乗っ取りの対策としてもよく言われるように、パッケージの開発者は二要素認証を利用することです。先に挙げたパッケージ管理ツールの公開リポジトリサービスは、どれも二要素認証をサポートしています。パッケージ開発者の方でまだ二要素認証の機能を有効にしていない方は、今すぐに有効にするようにしましょう。またパッケージの開発者ではない利用者側としてできる対策は、パッケージの自動アップデートを避け、バージョンを固定して利用することです。こうすることでパッケージ開発者が乗っ取られて悪意のあるコードの入った新しいバージョンのパッケージが登場したとしても、手元で利用しているパッケージには影響がありません。ただし、こうした場合は現在利用しているパッケージのバージョンに対するセキュリティアップデートを自動で受けることができなくなります。そのことに注意して、自分の利用しているパッケージに脆弱性がないかを常にチェックして、必要に応じてアップデートを手動で行う必要があります。
次に前述の二つ目のパターンである悪意を持ったコードを隠し持ったパッケージの対策です。これは、静的解析(ソースコードを読む、ソースコード解析ツールを使う等)や動的解析(実際に動かしてみて不審な動きがないか確認する等)によって問題がないかどうかを確認することです。とはいえ、静的解析や動的解析は非常に骨の折れる作業と思う方もいるでしょう。どうしても困難な場合は、後述する脆弱性データベースなどを利用する方法が考えられます。そのパッケージにすでに報告されている問題がないかどうかを最低限チェックするようにしましょう。また、あるパッケージは別のパッケージに依存していることがあり、そのパッケージに問題がなかったとしても依存先のパッケージに問題がある可能性もあります。これも後述する依存関係チェックツールなどで依存関係のチェックを行い、依存先のパッケージも問題がないかどうか確認します。
最後に三つ目のパターンである依存関係かく乱攻撃の対策です。これには、パッケージ管理ツールの設定で公開リポジトリからパッケージを取ってこないようにする方法があります。また、プライベートパッケージと同名のパッケージが公開リポジトリ側に存在しないことを確認したり、誰かに取得される前に自分でその名前のパッケージを取得してしまったりといった対策も考えられます。
パッケージの依存関係チェックと既知の脆弱性情報チェック
上記でご紹介した防御策のうち、パッケージの依存関係チェックと既知の脆弱性情報チェックを具体的に実施してみたいと思います。ここでは例として、先ほど取り上げた開発者のアカウントが乗っ取られて悪意のあるコードを埋め込まれたNode.jsの「rc」というパッケージを調査します。パッケージの依存関係のチェックにはGoogleが提供しているOpen Source Insights[8]というサービスを利用します。まずはOpen Source Insightsのサイトである
https://deps.dev/ にアクセスしてみましょう。

「Search for open source packages」と書かれている入力フィールドにrcと入力し、「All systems」と書かれたプルダウンリストからnpmを選択して「Search」ボタンをクリックします。

検索の結果、20のパッケージが発見されました。今回調査したいrcパッケージは一番上のものですので、それをクリックします。

するとパッケージの概要に関する情報が表示されます。具体的にはセキュリティアドバイザリ、ライセンス、依存しているパッケージの数、依存されているパッケージの数などです。

ここで左上の「Overview」の隣の「Dependencies」というタブをクリックすると、rcが依存しているパッケージを表示することができます。

というわけで、rcのバージョン1.2.8はdeep-extendのバージョン0.6.0、iniのバージョン1.3.8、minimistのバージョン1.2.5、strip-json-commentsのバージョン2.0.1という4つのパッケージに依存していることが分かりました。ここから各パッケージをクリックして、さらに依存先のパッケージについて調べることが出来ます。
続いて既知の脆弱性情報のチェックも実施してみましょう。既知の脆弱性情報のチェックには、これまたGoogleが提供しているOpen Source Vulnerability [9]というサービスを利用します。まずはOpen Source Vulnerabilityのサイトである
https://osv.dev/ にアクセスしてみましょう。

画面上部のvulnerability listとかかれたリンクをクリックすると、現在登録されている脆弱性のリストが表示されます。

さらにここから調査対象のパッケージを検索します。ここではNode.jsのnpmの公開パッケージである「rc」について調べますので、「Package or ID search」と書かれている入力フィールドにrcと入力し、「Select ecosystem」と書かれたプルダウンリストからnpmを選択します。

するとnpmのrcパッケージのバージョン2.3.9、1.3.9、1.2.9にはマルウェアが組み込まれているということが分かります。(Details)をクリックして詳細を見てみましょう。

おわりに
今回の記事ではプログラミング言語のパッケージ管理ツールを利用する際の危険性について説明しました。またその危険性を減らす方法のうち、パッケージの依存関係チェックと脆弱性情報チェックの方法を具体的にご紹介しました。パッケージ管理ツールは上手に利用すれば開発の効率を高めることできますが、利用する際には危険性も存在します。ご紹介しました対策などを参考にしていただけますと幸いです。
参考文献
- [1]
- [2]
- [3]
- [4]
- [5]
- [6]
- [7]
- [8]
- [9]
執筆者プロフィール
郡司 啓(ぐんじ さとし)
セキュリティ技術センター インテリジェンスチーム
おもに脅威情報を収集・分析し、それを必要とする人に届ける、といった事をしています。主な資格はCISSP、情報セキュリティスペシャリストなど。

執筆者の他の記事を読む
アクセスランキング