- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2019-02-03T09:28:24+09:00;2019-02-02T20:58:38+09:00","","")
RIGHT:&size(12){Category:[[:Plugin]]};
*ref.inc.php拡張。画像CGIを<img />タグに置くための''img''オプション [#va66f6a8]
-ページ: BugTrack
-ページ: [[BugTrack]]
-投稿者: [[sha]]
-優先順位: 低
-状態: 保留
-状態: 完了
-カテゴリー: 欲しいプラグイン
-投稿日: 2003-09-04 (木) 00:32:38
-バージョン: 1.4
-リリース予定バージョン: 1.5.2
**メッセージ [#n5dc6ec4]
現在、セキュリティホールにならないように拡張子が画像を示さないもの(画像CGI等)をref.inc.phpで<img />タグを出力しないようになっているかと思いますが、下記の動作を行うことによって許容することはできますでしょうか?
+%%refオプションに''img''を指定すると、引数のURLに対してhttp_request(URL,'HEAD')を送信。受信データのヘッダでContent-Typeが画像を示していれば、<img />タグを出力する。%%&color(red){→1回の表示につき、CGIが2回叩かれてしまう。また、リクエスト先によってContent-Typeを変化させることさえ可能(例えばPukiWiki-officialからのアクセスには 画像の、それ以外のサイトには画像でないものに)なので悪意のあるCGI(プログラム)に対しては無力};
+http_requestでキャッシュに保存して、ヘッダーのContent-Typeでキャッシュのファイルの表示方法を選択する
~重いかもしれませんが、それでも指定できた方がありがたい場合もありますので。「[[official:欲しいプラグイン/51]]」ご参照。
----
-こんな感じ。下記の変更を加えると出来たようです。やってみて気づきましたが、この方法だと1回表示する毎に、http_request()と<img src=... />で2回アクセスしてしまうんですね。そりゃそうか。'HEAD'メソッドといえども、CGIが動作して画像を生成してからでないとheaderが送信できないから当然と言えば当然か。-- [[sha]] &new{2003-09-04 (木) 19:57:53};
*** 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;
}
-やはり2回アクセスはなるべくなら避けたいところ。何かいい手はないものでしょうか?http_requestでキャッシュに保存して、ヘッダーのContent-Typeでキャッシュのファイルの表示方法を選択する、という方法なら1回で済みそうです。キャッシュをうまく使う方法ってどうすればよいでしょうか? -- [[sha]] &new{2003-09-04 (木) 21:38:32};
-ファイルに一旦蓄えて、1回表示したらそのファイルを削除するようにしてみました。なかなかうまく動いているようです。例えばこんな方法で、画像CGIへアクセスできる機能を正式版に実装していただければ幸いです。これ→「&ref(ref.inc.php);」
~ところで、バイナリの画像データへアクセスする必要から''proxy.inc.php''の''http_request()''の一部も変更する必要がありました。 -- [[sha]] &new{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;
}
-そもそも、is_url() が真の場合には、(拡張子を限定せず) img タグを許可しても OK な気がするんですが。。。 -- [[masao]] &new{2003-09-06 (土) 20:19:06};
--画像じゃないときに壊れていることを示すxアイコンを表示したくないからではないでしょうか?refは画像でなくても参照できることが売りですので。 -- [[sha]] &new{2003-09-11 (木) 18:09:19};
--えっと、すみません。意図が伝わらなかったようで。。。上記のパッチの処理のうち、Content-Type を確認する処理は不要ではないか。つまり、「 img オプションが指定された場合には、(Content-Type を考慮せず) img タグを表示して OK だと思います。」ということが聞いてみたいのですが…。 -- [[masao]] &new{2003-09-12 (金) 14:06:26};
--なるほど。imgオプションを指定したときには、#refの設置者に正常に表示されているか否かを判断してもらうということですね。設置者が面倒を見るなら、Content-Typeどころか拡張子すら見る必要はなさそうですが、そこまで任せてしまっていいものなんでしょうか。いずれにしても、確かに私の上の修正は大げさすぎる気はしていました。 -- [[sha]] &new{2003-09-13 (土) 15:20:15};
-メッセージに、セキュリティホールにならないように拡張子が画像を示さないものとあったので、いまさら何を(拡張子で判別ということですよぉ)と思ってソースを見てみましたが、attach で対応した内容が ref に生かされていない。ということだったんですね。でも、まだ img もありますから、忘れずに対応しておくのかなぁ? -- [[upk]]
-アフィリエイトのバナーを貼りたいがためにいろいろさがして、ここにたどり着きました。~これを,1.4.5にはめ込みたいのですが、どうしたらいいでしょうか? -- [[ひさ(なべ)]] &new{2005-03-17 (木) 17:53:06};
--アフィリエイトのバナーは画像以外の要素がありますので、[[official:自作プラグイン/htmlinsert.inc.php]]とか[[official:自作プラグイン/rothtml.inc.php]] を活用されたほうがよろしいかと思います。 -- [[teanan]] &new{2005-03-17 (木) 18:33:16};
-ご回答ありがとうございます。自分自身で使えば、それらのプラグインでもいいのですが、ほかの利用者にも貼ってもらいたいんです。それで、ちょっと悩んでいるのです。 -- [[ひさ(なべ)]] &new{2005-03-20 (日) 12:09:15};
-[[BugTrack2/69]] -- [[henoheno]] &new{2005-05-18 (水) 22:43:54};
-元発言のコメントにツッコミ追加。どこからのリクエストなのかによってContent-Typeを変化させることさえ可能(例えば攻撃URIを埋め込んだサイトからのアクセス((上で言う「確認のためのリモートアクセス」のIPアドレスとそのネットワークアドレスはどうしても固定的になるので判別可能))には 画像の、それ以外のサイトには画像でないものに)なので、悪意のある「リモート」ホスト(CGIプログラムや、それを隠蔽したURI)に対してはContent-Typeの事前チェックは無力です(穴があるということです)。 [[BugTrack2/69]] も参照あれ。-- [[henoheno]] &new{2005-05-18 (水) 23:09:50};
- [[BugTrack/2465]] imgプラグインが拡張子に関わらずimgタグで画像を表示するようになりました。refプラグインの動作は変わっていませんが、完了とします -- [[umorigu]] &new{2019-02-02 (土) 20:20:36};
//#comment
#comment