こんにちは、MAMEMARUです。
度々すみませんが、fckeditor のファイルアップロードについて質問がございます。
動画・音声ファイル(wmv,mov,wav.aif)を XOOPS_ROOT_PATH 側にアップロードしたいと思い(アップした動画ファイルを<embed>タグで埋め込むため)、config_and_auth.inc.php ファイルに以下のように記述しました。
$fck_allowed_extensions = array(
'jpg' => 'image/jp' ,
'jpeg' => 'image/jp' ,
'png' => 'image/png' ,
'gif' => 'image/gif' ,
'eps' => '' ,
'doc' => 'application/ms-word' ,
'xls' => 'application/ms-excel' ,
'txt' => 'text/plain' ,
'pdf' => 'application/pdf' ,
'swf' => 'application/x-shockwave-flash' ,
'fla' => '' ,
'mpeg' => '' ,
'mpg' => 'video/mpg' ,
'avi' => 'video/avi' ,
'wmv' => 'video/x-ms-wmv' ,
'mov' => 'video/quicktime' ,
'ppt' => 'application/ms-powerpoint' ,
'wav' => 'audio/wav' ,
'aif' => '' ,
) ;
しかし、swf 以外は「Invalid file」となってしまい、アップロードすることができませんでした。
'wmv' => '',
という風に元に戻すとアップロードは可能なのですが、XOOPS_TRUST_PATH 側にアップされてしまします。
config_and_auth.inc.php を変更するだけでは駄目なのでしょうか。
アドバイスを頂けたら幸いです。よろしくお願いいたします。
# 追記
config_and_auth.inc.php 21行目
$fck_resource_type_extensions = array(
'File' => array() ,
'Image' => array( 'jpeg' , 'jpg' , 'png' , 'gif' , 'eps' ) ,
'Flash' => array( 'swf' , 'fla' ) ,
'Media' => array( 'jpeg' , 'jpg' , 'gif' , 'swf' , 'fla' , 'avi' , 'mpg' , 'mpeg' , 'mov' , 'wmv' , 'mov' , 'wav' , 'aif' ) ,
) ;
このように、ファイル形式で振り分けるようにもしています。
MAMEMARUさん、こんにちは。
引用:
動画・音声ファイル(wmv,mov,wav.aif)を XOOPS_ROOT_PATH 側にアップロードしたいと思い(アップした動画ファイルを<embed>タグで埋め込むため)、config_and_auth.inc.php ファイルに以下のように記述しました。
$fck_allowed_extensions = array(
'jpg' => 'image/jp' ,
'jpeg' => 'image/jp' ,
'png' => 'image/png' ,
'gif' => 'image/gif' ,
'eps' => '' ,
'doc' => 'application/ms-word' ,
'xls' => 'application/ms-excel' ,
'txt' => 'text/plain' ,
'pdf' => 'application/pdf' ,
'swf' => 'application/x-shockwave-flash' ,
'fla' => '' ,
'mpeg' => '' ,
'mpg' => 'video/mpg' ,
'avi' => 'video/avi' ,
'wmv' => 'video/x-ms-wmv' ,
'mov' => 'video/quicktime' ,
'ppt' => 'application/ms-powerpoint' ,
'wav' => 'audio/wav' ,
'aif' => '' ,
) ;
しかし、swf 以外は「Invalid file」となってしまい、アップロードすることができませんでした。
'wmv' => '',
という風に元に戻すとアップロードは可能なのですが、XOOPS_TRUST_PATH 側にアップされてしまします。
fckxoopsバックエンドのアップローダはモードを2つ持っています。
trustモード:
trust側にアップロードされる
ファイル名はエンコードされた形で保存される
直アクセスはできず、転送スクリプトを通じてダウンロードできるのみ(その際に元のファイル名がデコードされてHTTPヘッダに渡される)
config側で、拡張子に対応する値を空にするとtrust側になる
rootモード:
root側にアップロードされる
ファイル名はランダムに振り直される(まったく保存されない)
httpd(Apache)によって直アクセスされる
config側で、拡張子に対応するmimeタイプを書くと、ファイルの中身がgetimagesize()によってチェックされ、その結果と食い違うと処理を停止する
つまり、getimagesize()でファイルの中身を真贋判定できないファイルについては、ROOT側に置けない、というのがfckxoopsの仕様となります。(=configだけではどうすることもできない)
現実に、画像ファイル以外については中身の真贋判定はほとんどのケースでできません。(getimagesize()も実は結構怪しいかもしれない)
私としても、真贋判定出来ないファイルをroot側に置かせたくはありませんから。
(そこが破られると、任意コード実行脆弱性となり、XSSなんかとは比較にならない即死穴となります)(2/27訂正)ファイル形式偽装だと、クライアントサイドスクリプトの任意実行脆弱性であり、即死は言い過ぎですね。埋め込み型なのでXSSよりはずっと危険ですが。
ただ、アップロードするのが管理者であるなら、その判定はスキップしても構わないという考え方はあるでしょう。
その場合は、
/common/fckeditor/editor/filemanager/connectors/php/functions.php
をHackすることになります。
227行目くらい
// check the file is valid (image mode only)
if( ! $trust_mode ) {
$check_result = @getimagesize( $new_filefullpath ) ;
if( $check_result === false && $GLOBALS['fck_isadmin'] ) {
// admin can upload non-image-files into root side
SendResultsHTML( 0 , $new_fileurl , $new_filename ) ;
return ;
}
if( ! is_array( @$check_result ) || empty( $check_result['mime'] ) || stristr( $check_result['mime'] , $fck_allowed_extensions[ $extension ] ) === false ) {
@unlink( $new_filefullpath ) ;
SendResultsHTML( '202', '', 'File extension does not match the file contents' , '' ) ;
} else {
管理者が画像以外のファイルをroot側に置きたい、というケースは今後も出てくるでしょうから、このコードは次のバージョンに反映させます。
GIJOEさん、詳細なご回答どうもありがとうございます。
引用:
ただ、アップロードするのが管理者であるなら、その判定はスキップしても構わないという考え方はあるでしょう。
その場合は、
/common/fckeditor/editor/filemanager/connectors/php/functions.php
をHackすることになります。
227行目くらい
// check the file is valid (image mode only)
if( ! $trust_mode ) {
$check_result = @getimagesize( $new_filefullpath ) ;
if( $check_result === false && $GLOBALS['fck_isadmin'] ) {
// admin can upload non-image-files into root side
SendResultsHTML( 0 , $new_fileurl , $new_filename ) ;
return ;
}
if( ! is_array( @$check_result ) || empty( $check_result['mime'] ) || stristr( $check_result['mime'] , $fck_allowed_extensions[ $extension ] ) === false ) {
@unlink( $new_filefullpath ) ;
SendResultsHTML( '202', '', 'File extension does not match the file contents' , '' ) ;
} else {
上記のようにハックしたところ、動画ファイルをROOT側にアップロードすることができました。
最終的には、モデレータレベルとして作成しているユーザ数名にも権限を与えた、以下のようなコードを追記しました。
if( $check_result === false && $GLOBALS['fck_isadmin'] || $check_result === false && $GLOBALS['fck_uploadable_groups'] ) {
// admin can upload non-image-files into root side
SendResultsHTML( 0 , $new_fileurl , $new_filename ) ;
return ;
}
問題なく動作しているようです。
どうもありがとうございます
引用:
管理者が画像以外のファイルをroot側に置きたい、というケースは今後も出てくるでしょうから、このコードは次のバージョンに反映させます。
ご検討ありがとうございます。次のバージョンを楽しみにしています!