KCFinderの設置の注意点
登録日:2017-05-11
ググッてみたけど、あんまり書いてなかったので。
今回のネタはプログラマさんから見たら、「んなこと、知っとるわ~!」という内容と思いますが、WEB業界というもの、みんながベテランではないので、知らない人のためにお役に立てられれば良いかと思います。
CMSの管理画面でWYSIWYGを使うのはイマドキ当たり前なんですが、その中でも「CKEditor」と無料で使える「KCFinder」の組み合わせは人気がありますね。
で、この「KCFinder」の設置方法をググってみても、セキュリティについてはサラッと書いてあるだけのものが多く、実際危ない状態で晒されているサイトが散在します。
設置をしくじると誰でもアクセスできてしまう
右はFCKeditorのファイルブラウザーの画面です。
この画面、本来は管理画面をログイン認証してから使うものですね。
お使いのCMSで、ファイルブラウザーの画面を開き、そのアドレスをコピペして、ログアウトしてる状態で直接ブラウザで開いてみてください。
(別のブラウザで開いてみてもよいです)
エラー画面やログイン画面にリダイレクトされればひとまず大丈夫です。
しか~し、普通に開いてしまった場合、設定をしくじってます。
(どこの誰でも、ファイルの削除やリネーム、アップロードができてしまいます。)
「そんなのアドレスがバレなきゃ大丈夫さ!」と思った方も多いかもしれませんが、ある程度の技術者になると、「KCFinder」を使っているサイトを探し出して(っていうかGoogleである程度出てくる)、さらにこのアドレスも予想されてしまいます。
セキュリティの世界では「強制ブラウジング」といって、初歩的な攻撃となります。
セキュアな設定の松竹梅
設定をしくじっていた!とにかく早く直したい!となりますが、その前に、なぜこう状態になるのかを理解しておくことが重要です。
非プログラマ系の人にはちょっと面倒ですが、できれば読んでいただきたいです。
最初に本来のシステムの流れをざっくり説明します。
大抵のCMSはまず初めに「ユーザー認証」という仕組みが動きます。ログインのことです。
正しいユーザーであれば、セッションと呼ばれる切符を発行します。
その後、メインの管理プログラムやファイルマネージャーであるKCFinderが、処理の度にセッションを確認し、正しいユーザーのアクセスということを確認します。
そして、このセッションが確認できない場合に、強制ログアウトやエラーを出すようになっています。
ところが、KCFinderは管理プログラムに、別の人が作ったプログラムを後付けする格好なので、設置時にセッションを確認するよう設定しなければなりません。
よく「KCFinder」の設置を紹介しているサイトを見ると、
config.phpの
「’disabled’ => true,」を「’disabled’ => false,」に書き換えれば動きます。
と出ていますが、セッションをきちんと処理しないと、KCFinderはどこからでも誰とでもアクセスを許してしまいます。
本来はここで認証について書くべきなんですが、使っている認証プログラムやセッションの使い方によって、それぞれ異なる(自分でコードを書く必要が出る場合がほとんどじゃないかな)ので、説明する人も説明しきれないと思います。
ということで、松の設定。
プログラムを少々たしなむ方であれば、お使いの認証システムが発行するセッションをチェックするPHPコードを自力で作成し、「config.php」または「conf/config.php」に記載してください。
1.config.phpで認証を通過したアクセスのみ「disabled’ => false,」にして、それ以外は「disabled’ => true,」にするといった方法
2.config.phpの最初に認証チェックしてNGならログイン画面に戻す方法
の2通りを試しましたが、1の場合は不正にアクセスするとphpのエラーでフルパスが表示されるので、2にしていたところ、これだと今度はCSRFができてしまうことに気づきまして、config.phpの他にupload.phpにも認証を通過しないと、エラーを返すようにしました。(ver 2.51、3.12でテスト済み)
※upload.phpのみに記述すると、GUIは表示されてしまうので、ちょっとどんくさいですが2ファイルに記述しました。
オレはプログラマじゃないからわかんねぇよ!竹の設定
「KCFinder」のディレクトリにBasic認証を掛けちゃいましょう。
これならサーバーのコントロールパネルからID/PASSが設定できるでしょうから、プログラムが書けない人でもすぐに対応できます。
(アップロードディレクトリは上位階層にしておくことを忘れずに!)
ただ、CMSのログインとは別にKCFinderのログイン画面が出るので、うっとうしいとは思いますが、とりあえずの安全性を高める手段としてはやった方がよいと思います。
ログインが2回出るなんてクライアントに言えない!梅の設定
空耳でしょうか?ボクには現場からこういう声が聞こえてくる気がするんです。とくに営業さんが制作にガンガン言ってるカンジ。
これは本当に非推奨ですが、後にプログラマさんにしっかり松の設定をしてもらうとして、場しのぎにやるなら、「***/kcfinder」のディレクトリ名を「../ottotto」などkcfinderと関係なさそうなディレクトリ名に変えてしまうというものです。
これは単に予想されにくいアドレスにする
だけの話で、危ないは危ないです。
できれば、アップロードディレクトリも下層ではなくルートに設定するなどして、とにかく予想されないようにしてください。
この場合、CKEditorの「config.js」のパス変更もお忘れなく。
ホントはこんなのアカンですよ。
あと念の為にサーバーブラウザのページタイトルを変更
サーバーブラウザを開くと、アップローダーの画面が出るわけですが、このページのタイトルはデフォルトで「KCFinder: /images」や「KCFinder: /files」です。
ちゃんと認証を設定していないと、Google様にこのタイトルがインデックスされて、悪い輩に検索されることがありますので、念の為に「/tpl/tpl_browser.php」を開いて、<title>~</title>の中身を変えておくか、メタタグでnoindexを設定しておいても良いかと思います。
余談ですが、日本語ファイルのアップロードについて
日本語のファイル名はアップロードしちゃあきまへんよ!とクライアントに伝えても、結構な確率で日本語ファイルをアップしちゃいますね。
これ、エラーの原因(サーバーブラウザが開かなくなったり)になりますんで、せめて日本語ファイル名の場合は、URLエンコードして保存するようにしておくのが手っ取り早いかと思います。
core/browser.php内
266行目あたり
if (is_array($this->file['name'])) {
$return = array();
foreach ($this->file['name'] as $i => $name) {
$name =urlencode($name);//この一行を追記
$return[] = $this->moveUploadFile(array(
'name' => $name,
'tmp_name' => $this->file['tmp_name'][$i],
'error' => $this->file['error'][$i]
です。
アドレスはそんなに漏れるのか?
梅の設定で安心してしまわないように、ちょっと書き足します。
例えば以下の状況は起こりうりますか?
1.リニューアルで別の制作会社に変わられた。
2.コーダーやプログラマが憎しみをもって辞めた
3.外注先にヤバそうな人がいる
これらの条件は、制作したファイルが外部に渡る可能性です。
制作者や制作会社というのは、だいたい作り方にクセがあるので、他のサイトも同じような設計になっていることがほとんどで、一つの脆弱性が判明すると、それがセキュリティリスクにつながります。
万に一人でも、アウトな人が上記条件の中に潜んでいたら、積み上げた信用も台無しです。
サーバー設定によっては大変なことに?
2019.12.2追記
KCFinderではデフォルトでphpファイルのアップロードは弾くようになっていますが、htmlは通過します。
これを悪用すると、WebShell等のphpを拡張子「html」にしてアップロードすることで、サーバーの中身がやられ放題になってしまいます。よって、念の為config.phpの「deniedExts」にhtml htm shtmlも追加しておくことをお勧めします。
ちなみに、不正ファイルをアップされた中身をみると、○○.php5や○○.php7など「deniedExts」にデフォルトで記載のない拡張子のものが大量にあります。
昔は .php4とか見ましたが、今でもPHPのバージョンを拡張子で判定して動かすサーバーがあるのでしょうか?
こういうサイトもあったので、探せばあるんだな・・・
PHP7.0の設定方法(外部リンク)
PHP サポート情報(da63以降)
この記述をみると .php7や.php56 でも動かす記載があります。
サーバーによっては、config.phpの「deniedExts」に追記した方がよさげですね。
難しいわ・・ホント。
余談ですが IP分散って実際どうなんでしょうね~。
ということで、config.phpの「deniedExts」は以下のファイルを指定しておいたほうがよいかも。
'deniedExts' => "exe com msi bat cgi pl php phps phtml php3 php4 php5 php56 php7 html htm shtml py pyc pyo pcgi pcgi3 pcgi4 pcgi5 pchi6 xml txt eaz",
最後に
今回これを書いたのは、KCFinderのことが気になって調べたところ、結構危ない状態のサイトがわんさか出てきたからです。
中にはとあるJA(農協)のサイトもありました。
設置方法の問題で、ソフト自体の脆弱性という訳ではないので、IPAにも通告できないでしょう。
世の中、愉快犯なんてそんなにいないだろう!と思いたいですが、最近は子供のうちからプログラムを覚えさせたい!という親も多く、プログラムスキルを持った人の低年齢化が進むでしょう。
そういう子供の中にはイタズラっ子もいるでしょうから、遊び半分でハッキング行為をする人も増えるんじゃないかな~と思います。
あと、今回の記事はKCFinder 2.51と3.12で検証してます。
尚、私も全知全能ではないので、内容に間違いがあれば訂正します。