BowerのZIPアーカイブ展開における深刻なセキュリティ脆弱性
2019年1月31日
0 分で読めます今月初め、人気のWebパッケージマネージャーBowerにアーカイブ展開の脆弱性があることが判明しました。現在、関連するセキュリティインシデントが2件確認されており、いずれも対処するためのアップデートがリリースされています。
任意のファイル書き込みによってリモートコマンドインジェクションにつながる可能性がある問題は、Bower 1.8.6で修正されました。これは、Bowerが使用するオープンソース依存関係Zip Slipの脆弱性が、decompress-zip依存関係で見つかったことに起因します。
.tar.gzアーカイブのシンボリックリンク(symlink)の脆弱性を悪用した任意のファイル書き込みは、Bowerがアーカイブを展開する方法に起因するもので、Bower 1.8.8で修正されました。
Webpack、yarn、npmレジストリの登場でBowerを取り巻く状況は変わりましたが、今も使われています。現在はより人気のあるパッケージマネージャーが登場し、JavaScriptではnpmが事実上の標準レジストリとなっています。それでもBowerはパッケージマネージャーとして広く利用されており、月間ダウンロード数は約200万件に上ります。このことからも、今回のセキュリティ問題の深刻さが分かります。
2019年1月1日、セキュリティ研究者のskyn3tは、HackerOne上でNode.jsセキュリティワーキンググループに、Bowerがtarアーカイブを展開する方法に起因する、シンボリックリンクの不適切な検証を利用した任意のファイル書き込みを報告しました。
バグのトリアージ後まもなく、BowerコアチームのAdam Stankiewiczがレポートのレビューに招かれ、速やかに問題を確認しました。そしてセキュリティ上の懸念に対処する修正をBower 1.8.8でリリースしました。
アーカイブ展開時の悪意あるパストラバーサル
攻撃者が、Bowerでインストールされるパッケージ用に細工したZIPアーカイブを作成すると、パストラバーサルが発生する可能性があります。その結果、アーカイブを展開する想定のルートディレクトリの外部にファイルが展開されてしまいます。
以下の概念実証(POC)は、Node.jsセキュリティワーキンググループのHackerOneプログラムに対してskyn3tが公開したセキュリティレポートに基づいています。シンボリックリンクの安全でない処理によって、任意のファイル書き込みが発生する仕組みを示しています。
悪意あるパッケージアーカイブ
アーカイブでは、まずディレクトリへのシンボリックリンクを作成し、そのリンク先のディレクトリにファイルを配置する必要があります。ただし、このディレクトリ構造を再現するには、悪意あるアーカイブを手作業で作成する必要があります。
まず、悪意あるパッケージ用のディレクトリと、Bower用のデフォルトのpackage.jsonファイルを作成し、/tmpへのシンボリックリンクを作成します。
次に、このパッケージのtarballアーカイブを作成します。このとき、圧縮しないようにします。

難しいのは、こちらで用意したファイルを/tmpディレクトリに、つまりアーカイブ内のmySpecialDirectory/に配置することです。このファイル名はすでにリンクとして使われているため、ローカルのファイルシステム上でそのまま再利用することはできません。
この問題を解決するため、アーカイブの標準的なコア機能に立ち戻り、アーカイブ内のデータを操作します。tarファイルでは、ファイルの追加など既存アーカイブを更新できるため、ここから抜け出すための仕掛けを作成できます。
リンクを削除し、その場所にディレクトリを作成して、その中に独自のファイルを作成します。次に、tarの更新機能を使って、そのファイルだけをアーカイブに追加します。
スクリーンショットから分かるように、アーカイブには/tmpディレクトリへのシンボリックリンクと、こちらで作成した悪意あるファイルが含まれています。

圧縮アーカイブは、tarアーカイブと同じ方法では操作できない点に注意が必要です。そのため、アーカイブに悪意ある細工を施した後でgzip圧縮します。
Bowerにインストールを実行させる
ホームフォルダーの~/tmpにtar.gzアーカイブを用意できたので、ローカルファイルシステムからBowerのインストールを実行し、パッケージがどのように展開されるかを確認します。

ご覧のとおり、使用されているのはBower 1.8.7です。悪意あるパッケージをインストールすると、こちらで用意した悪意あるファイルがシステムの/tmpディレクトリにインストールされました。
脆弱性への対処
Bowerはtar、tar.gz、zipの各アーカイブ形式に対応しています。zipパッケージに影響する同様の脆弱性は、すでにdecompress-zipの修正によって解決されていましたが、tarとtar.gzには脆弱性が残っていました。
tarおよびtar.gzの脆弱性に対して最終的に提供された修正では、インストール対象のパッケージ内にあるシンボリックリンクを無視することで問題を緩和しました。セキュリティ問題への対処として、ユーザーがアップグレードできるBowerの新バージョン1.8.8がリリースされています。
2018年初頭、Snykのセキュリティリサーチチームは、任意のファイル書き込みにつながるアーカイブ展開の悪用について広範な調査を実施し、「Zip Slip」というセキュリティ脆弱性の名称を提唱しました。深刻度が重大な場合、リモートコマンド実行や機密性の高いシステム設定ファイルの上書きにつながる可能性もあります。
Zip Slipの調査により、さまざまなエコシステムにわたって数千もの脆弱なプロジェクトが見つかりました。影響を受けたプロジェクトには、Apache、Pivotal、Amazonなどのものが含まれていました。
まとめ
任意のファイル書き込みを引き起こす悪意あるパッケージを意図的に作成する方法を見てきました。しかし、問題は悪意あるパッケージをダウンロードするケースに限りません。HTTPSではない通信など、安全でない経路でパッケージを取得する場合、中間者攻撃が可能になります。
ファイル展開に関する問題は今に始まったことではありません。1991年のPhrackの記事では、こうしたZIP展開の攻撃手法を使ってBBSをハッキングする方法が解説されていました。この分野の研究が進むにつれて、ライブラリやアプリケーションでZip Slipの脆弱性が今後も発見される可能性は高いでしょう。
シンボリックリンクが許可されている場合でも、ユーザーが制御するアーカイブの取り扱いは危険です。他のユーザー入力と同じように、十分な注意を払って処理してください。
重要なポイント
できるだけ早くBower 1.8.8にアップグレードしてください。
さまざまなプログラミング言語のエコシステムにおける脆弱なコードの例や、コードで同様のセキュリティ脆弱性を回避する方法については、Zip Slip Cheat Sheetをご覧ください。



