Category::Plugin

ref.inc.php拡張。画像CGIを<img />タグに置くためのimgオプション

メッセージ

現在、セキュリティホールにならないように拡張子が画像を示さないもの(画像CGI等)をref.inc.phpで<img />タグを出力しないようになっているかと思いますが、下記の動作を行うことによって許容することはできますでしょうか?

  1. refオプションにimgを指定すると、引数のURLに対してhttp_request(URL,'HEAD')を送信。受信データのヘッダでContent-Typeが画像を示していれば、<img />タグを出力する。→1回の表示につき、CGIが2回叩かれてしまう。また、リクエスト先によってContent-Typeを変化させることさえ可能(例えばPukiWiki-officialからのアクセスには 画像の、それ以外のサイトには画像でないものに)なので悪意のあるCGI(プログラム)に対しては無力
  2. http_requestでキャッシュに保存して、ヘッダーのContent-Typeでキャッシュのファイルの表示方法を選択する

    重いかもしれませんが、それでも指定できた方がありがたい場合もありますので。「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.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&amp;refimg_no='.rawurlencode($num).
+       '&amp;page='.rawurlencode($page).'&amp;ctype='.rawurlencode($ctype).'&amp;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;
  }


*1 上で言う「確認のためのリモートアクセス」のIPアドレスとそのネットワークアドレスはどうしても固定的になるので判別可能

添付ファイル: fileref.inc.php 1153件 [詳細]

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-02-02 (土) 20:58:38
Site admin: PukiWiki Development Team

PukiWiki 1.5.4+ © 2001-2022 PukiWiki Development Team. Powered by PHP 8.2.12. HTML convert time: 0.334 sec.

SourceForge