現在、セキュリティホールにならないように拡張子が画像を示さないもの(画像CGI等)をref.inc.phpで<img />タグを出力しないようになっているかと思いますが、下記の動作を行うことによって許容することはできますでしょうか?
重いかもしれませんが、それでも指定できた方がありがたい場合もありますので。「official:欲しいプラグイン/51」ご参照。
*** ref.inc.php-119 Thu Sep 4 15:03:33 2003 --- ref.inc.php Thu Sep 4 19:55:42 2003 *************** *** 34,35 **** --- 34,37 ---- 画像を展開しない + -img~ + HEADメソッドでContent-Typeを確認 -zoom~ *************** *** 157,158 **** --- 159,161 ---- 'noimg' => FALSE, // 画像を展開しない + 'img' => FALSE, // 画像のContent-Typeを確認 'zoom' => FALSE, // 縦横比を保持する *************** *** 193,195 **** ! $is_image = (!$params['noimg'] and preg_match("/\. (gif|png|jpe?g)$/i",$name)); if (REF_URL_GETIMAGESIZE and $is_image and (bool)ini_get ('allow_url_fopen')) --- 196,199 ---- ! $is_image = (!$params['noimg'] and preg_match("/\. (gif|png|jpe?g)$/i",$name)) || ! ($params['img'] and plugin_ref_is_type_image($name)); if (REF_URL_GETIMAGESIZE and $is_image and (bool)ini_get ('allow_url_fopen')) *************** *** 376,377 **** --- 380,395 ---- $params['_args'][] = $val; + } + // HEADメソッドでContent-Type確認 + function plugin_ref_is_type_image($url){ + $resp = http_request($url,'HEAD'); + if ( (integer)($resp['rc'] / 100) != 2 ) return FALSE; + $lines = explode("\r\n",$resp['header']); + foreach ( $lines as $line ){ + if ( preg_match('/^Content-Type\:\s*image\/(gif|png|jpe?g)\s*$/i', $line) ){ + return TRUE; + } + } + return FALSE; }
ところで、バイナリの画像データへアクセスする必要からproxy.inc.phpのhttp_request()の一部も変更する必要がありました。 -- sha 2003-09-06 (土) 12:30:55
*** proxy.php-102 Sat Sep 06 12:16:38 2003 --- proxy.php Sat Sep 06 12:22:22 2003 *************** *** 85,87 **** { ! $response .= fgets($fp,4096); } --- 85,87 ---- { ! $response .= fread($fp,4096); }
*** ref.inc.php-119 Sat Sep 06 12:14:34 2003 --- ref.inc.php Sat Sep 06 12:11:14 2003 *************** *** 5,7 **** // $Id: ref.inc.php,v 1.19 2003/06/30 05:06:48 arino Exp $ ! // --- 5,7 ---- // $Id: ref.inc.php,v 1.19 2003/06/30 05:06:48 arino Exp $ ! // modified by sha 2003/09/06 12:09:00 *************** *** 34,35 **** --- 34,37 ---- 画像を展開しない + -img~ + ヘッダーのContent-Typeで画像を確認 -zoom~ *************** *** 157,158 **** --- 159,161 ---- 'noimg' => FALSE, // 画像を展開しない + 'img' => FALSE, // Content-Typeで画像を確認 'zoom' => FALSE, // 縦横比を保持する *************** *** 194,195 **** --- 197,208 ---- $is_image = (!$params['noimg'] and preg_match("/\.(gif|png|jpe?g)$/i",$name)); + if ( !$is_image and $params['img'] ){ + $ret = plugin_ref_getimage($name,$page); + if ( $ret !== FALSE ) { + list($ctype,$num,$md5) = $ret; + $url = $script.'?plugin=ref&refimg_no='.rawurlencode($num). + '&page='.rawurlencode($page).'&ctype='.rawurlencode($ctype).'&md5='.rawurlencode($md5); + $url2 = ''; + $is_image = TRUE; + } + } if (REF_URL_GETIMAGESIZE and $is_image and (bool)ini_get('allow_url_fopen')) *************** *** 376,377 **** --- 389,441 ---- $params['_args'][] = $val; + } + // Content-Typedで画像を確認 + function plugin_ref_getimage($url,$page){ + global $script; + $resp = http_request($url); + if ( (integer)($resp['rc'] / 100) != 2 ) return FALSE; + $lines = explode("\r\n",$resp['header']); + foreach ( $lines as $line ){ + if ( preg_match('/^Content-Type\:\s*image\/(gif|png|jpe?g)\s*$/i',$line,$match)){ + $md5 = md5($resp['data']); + $num = plugin_ref_writeimage($url,$page,$resp['data']); + return array($match[1],$num,$md5); + } + } + return FALSE; + } + function plugin_ref_writeimage($url,$page,$data){ + list($num,$file) = plugin_ref_make_filename($url,$page); + $fp = fopen($file,'wb') or die_message('cannot write '.$file); + flock($fp,LOCK_EX); + fwrite($fp,$data); + fflush($fp); + flock($fp,LOCK_UN); + fclose($fp); + return $num; + } + function plugin_ref_make_filename($url,$page){ + $num = 0; + do { + $num ++; + $id = encode($page).'_'. $num; + $file = CACHE_DIR . $id . '.refimg'; + } while( file_exists($file) ); + return array($num,$file); + } + function plugin_ref_action(){ + global $vars; + if ( !array_key_exists('refimg_no',$vars) or !array_key_exists('md5',$vars) or + !array_key_exists('page',$vars) or !array_key_exists('ctype',$vars) ) { + return array('msg'=>'Error', 'body'=>'cannot be executed as command.'); + } + $oldmd5 = $vars['md5']; + $refimg_no = $vars['refimg_no'] + 0; + $file = CACHE_DIR . encode($vars['page']) .'_'. $refimg_no .'.refimg'; + $ctype = $vars['ctype']; + if ( file_exists($file) and $oldmd5 == md5_file($file) ) { + header('Content-Type: image/' . trim($ctype)); + @readfile($file); + @unlink($file); + } + die; }