外部リンクをリダイレクトページ経由にすることで、Refererを消す

  • ページ: BugTrack
  • 投稿者: pai
  • 優先順位: 低
  • 状態: 完了
  • カテゴリー: 本体新機能
  • 投稿日: 2007-06-16 (土) 02:13:51
  • バージョン: 1.4.7
  • リリース予定バージョン: 1.5.2

メッセージ

Wiki上の外部リンクをクリックすると、リンク先のページにはRefererとしてWikiのURL(つまり、ページ名も)が渡ってしまいます。社内システムや非公開URLにあるWikiなどでは、顧客名やプロジェクト名等が漏れることが、問題となることがあります。このような場合は、WikiのURLが推測できないリダイレクトページを経由させることで、WikiのURLが漏洩しないようにすることができます。

パッチ例 (2007年6月実装)

pukiwiki.ini.php

  //   NOTE: Keep (page-name + attach-file-name) <= PKWK_QUERY_STRING_MAX
  define('PKWK_QUERY_STRING_MAX', 640); // Bytes, 0 = OFF
  
+ function        convertglobalurl($href) {
+         if ((preg_match("%^https?://".SERVER_NAME."%", $href)))
+                 return $href;
+         return "../../redirect.php?".urlencode($href);
+ }
+ 
  /////////////////////////////////////////////////
  // Experimental features

lib/init.php(下記の部分はincludeの後に移動する)

! define('S_COPYRIGHT',
!         '<strong>PukiWiki ' . S_VERSION . '</strong>' .
!         ' Copyright &copy; 2001-2006' .
!         ' <a href="'.convertglobalurl("http://pukiwiki.sourceforge.jp/").'">PukiWiki Developers Team</a>.' .
!         ' License is <a href="'.convertglobalurl("http://www.gnu.org/licenses/gpl.html").'">GPL</a>.<br />' .
!         ' Based on "PukiWiki" 1.3 by <a href="'.convertglobalurl("http://factage.com/yu-ji/").'">yu-ji</a>'
! );

lib/make_link.php

***************
*** 385,391 ****
                  } else {
                          $rel = ' rel="nofollow"';
                  }
!                 return '<a href="' . $this->name . '"' . $rel . '>' . $this->alias . '</a>';
          }
  }
  
--- 385,391 ----
                  } else {
                          $rel = ' rel="nofollow"';
                  }
!                 return '<a href="' . convertglobalurl($this->name) . '"' . $rel . '>' . $this->alias . '</a>';
          }
  }
  
***************
*** 423,429 ****
  
          function toString()
          {
!                 return '<a href="' . $this->name . '" rel="nofollow">' . $this->alias . '</a>';
          }
  }
  
--- 423,429 ----
  
          function toString()
          {
!                 return '<a href="' . convertglobalurl($this->name) . '" rel="nofollow">' . $this->alias . '</a>';
          }
  }
  
***************
*** 533,539 ****
  
          function toString()
          {
!                 return '<a href="' . $this->url . $this->anchor . '" title="' .
                          $this->name . '" rel="nofollow">' . $this->alias . '</a>';
          }
  }
--- 533,539 ----
  
          function toString()
          {
!                 return '<a href="' . convertglobalurl($this->url . $this->anchor) . '" title="' .
                          $this->name . '" rel="nofollow">' . $this->alias . '</a>';
          }
  }
***************
*** 711,717 ****
          $s_page = htmlspecialchars(strip_bracket($page));
          $s_alias = ($alias == '') ? $s_page : $alias;
  
!         if ($page == '') return '<a href="' . $anchor . '">' . $s_alias . '</a>';
  
          $r_page  = rawurlencode($page);
          $r_refer = ($refer == '') ? '' : '&amp;refer=' . rawurlencode($refer);
--- 711,717 ----
          $s_page = htmlspecialchars(strip_bracket($page));
          $s_alias = ($alias == '') ? $s_page : $alias;
  
!         if ($page == '') return '<a href="' . convertglobalurl($anchor) . '">' . $s_alias . '</a>';
  
          $r_page  = rawurlencode($page);
          $r_refer = ($refer == '') ? '' : '&amp;refer=' . rawurlencode($refer);

plugin/showrss.inc.php

***************
*** 85,91 ****
                                  $link  = $item['LINK'];
                                  $title = $item['TITLE'];
                                  $passage = get_passage($item['_TIMESTAMP']);
!                                 $link = '<a href="' . $link . '" title="' .  $title . ' ' .
                                          $passage . '" rel="nofollow">' . $title . '</a>';
                                  $this->items[$date][] = $this->format_link($link);
                          }
--- 85,91 ----
                                  $link  = $item['LINK'];
                                  $title = $item['TITLE'];
                                  $passage = get_passage($item['_TIMESTAMP']);
!                                 $link = '<a href="' . convertglobalurl($link) . '" title="' .  $title . ' ' .
                                          $passage . '" rel="nofollow">' . $title . '</a>';
                                  $this->items[$date][] = $this->format_link($link);
                          }
--- interwiki.inc.php.070911	2007-09-11 22:52:09.078125000 +0900
+++ interwiki.inc.php	2007-09-11 22:53:10.687500000 +0900
@@ -18,7 +18,7 @@
 	if ($url === FALSE) return plugin_interwiki_invalid();
 
 	pkwk_headers_sent();
-	header('Location: ' . $url);
+	header('Location: ' . convertglobalurl($url));
 	exit;
 }
 
--- lookup.inc.php.070911	2007-09-11 22:52:25.593750000 +0900
+++ lookup.inc.php	2007-09-11 22:53:00.390625000 +0900
@@ -59,7 +59,7 @@
 	}
 
 	pkwk_headers_sent();
-	header('Location: ' . $url); // Publish as GET method
+	header('Location: ' . convertglobalurl($url)); // Publish as GET method
 	exit;
 }
 ?>

redirect.php例

<?php
$target = htmlspecialchars(urldecode(@$_SERVER["QUERY_STRING"]), ENT_QUOTES);
$meta = "";
if (ereg('^https?://[-a-zA-Z0-9]+\.somedomain\.com/', @$_SERVER["HTTP_REFERER"]))
	$meta = '<META http-equiv="refresh" content="5;url='.$target.'">';
?>
<HTML><HEAD><TITLE>redirect.php</TITLE><?=$meta ?></HEAD><BODY>

<H1>redirect to <A href="<?=$target ?>"><?=$target ?></A></H1>

<HR>
</BODY></HTML>

問題点

  • 外部URLを参照する画像は、サーバがproxyになって転送する必要がありそう
  • plugin/back.inc.php は利用できなさそう
  • plugin/amazon.inc.php は利用できなさそう
  • 要修正: SERVER_NAME中の.が正規表現エスケープされていない
  • 要修正: pukiwiki.ini.phpをincludeした直後に、if(!function_exists("convertglobalurl")){function convertglobalurl($href){return $href;}}を入れ、旧バージョンのpukiwiki.iniを使った場合でも動作するようにする。
    • [070726:pai]真偽が逆だったので修正。リストをforeachで回した方が拡張性があるかも。
  • 要修正: ポート番号がついている場合にリダイレクトされない(手動でリンクをクリックすれば問題ない)。'^https?://[-a-zA-Z0-9]+\.somedomain\.com(:[0-9]+)?/'ならOK?

コメント

  • はじめて書くので、何か問題があればコメントください。 -- pai 2007-06-16 (土) 02:24:53
  • 関連 teanan:自作プラグイン/jumpto.inc.php -- 2007-06-16 (土) 03:44:05
  • ありがとうございます。diffは -u (unified) で出せば小さくなりますよ。 -- henoheno 2007-06-16 (土) 12:44:13
  • 外部Link確認Script http://smith.xrea.jp/?Management%2FWikiModification#w09e0846 -- 2007-06-17 (日) 00:23:37
  • official:質問箱4/77 -- 2007-06-17 (日) 02:55:36
  • official:自作プラグイン/exlink.inc.php -- 2007-06-17 (日) 02:56:32
  • redirect.phpと、問題点の追加をおこないました。 -- pai 2007-06-18 (月) 03:20:32
  • いろいろコメントありがとうございます。redirect.php については別のページにて練らせていただいて構いませんでしょうか。コードはcvs:../develあたりに追加しますが、ライセンスについて念のため確認させて下さい。PukiWikiと同じとして問題ないでしょうか? -- henoheno 2007-06-24 (日) 23:52:16
  • リプライが遅くなり申し訳ありません。ライセンスはPukiWikiと同じで問題ありません。 -- pai 2007-07-26 (木) 22:41:53
    • コメントありがとうございます。以前から作っているredirect.php とマージさせる形で、各種用途に使えるものができればいいのではないかと思っています。 -- henoheno 2007-08-05 (日) 19:08:09
  • Location:ヘッダによるリダイレクトを見落としていたので、追加しました。 -- pai 2007-09-11 (火) 23:22:08

2018年3月版実装

JavaScriptを利用して、本体実装への影響を少なくしつつリファラ対応を入れました。(by umorigu)

  • 外部リンク用のクッションページを作成 (external_linkプラグイン)
  • JavaScriptで実装 (ページ内のすべてのリンクに対処可能。個別のプラグインでの処理が不要)
    • 期待動作のためにはモダンブラウザを利用する必要がある(IEならIE9以降)
    • 主な要件: JSON.parse(), document.querySelectorAll(), CSS3
  • 設定 $external_link_cushion_page 0(Disabled) or 1(Enabled) in pukiwiki.ini.php
    • デフォルトは0
  • 設定 $external_link_cushion in pukiwiki.ini.php
    • 'internal_domains': 「内部サイト」とみなすサイト(FQDN)のリスト。ワイルドカード '*.' を先頭にのみ利用可能
    • 'silent_external_domains': 「外部サイトであるが、外部リンクアイコンを表示しないドメインのリスト
  • 外部リンクアイコン image/external_link.png を追加
  • 外部リンクアイコンをCSSで表示 (CSS3 の ::after疑似要素)
  • 設定をJSONでHTMLに埋め込み、JavaScriptで読み出し、リンク先の書き換えを行う
  • サーバー要件: PukiWiki文字コード設定:UTF-8, PHP5.4以降
  • クライアント要件: JavaScript有効, JSON.parse(), document.querySelectorAll(), Array.indexOf(), CSS3
  • imgタグのサポートはない。(imgタグによる画像読み込みの場合には画像があるサーバーにリファラが送信されてしまう) 必要な場合はBugTrack/2462や本ページ(BugTrack/2247)の前半の実装を使って別途対応すること

設定例

// Show External Link Cushion Page
// 0: Disabled
// 1: Enabled
$external_link_cushion_page = 1;
$external_link_cushion = array(
       // Wait N seconds before jumping to an external site
       'wait_seconds' => 5,
       // Internal site domain list
       'internal_domains' => array(
               'localhost',
               '*.example.com',
       ),
       // Don't show extenal link icons on these domains
       'silent_external_domains' => array(
               'pukiwiki.osdn.jp',
               'pukiwiki.example.com',
       ),
);

コメント (2018年3月実装以降)

  • JavaScriptで実装しました -- umorigu 2018-03-22 (木) 02:29:54
  • file:プロトコルの時にクッションページを挟まないようにしました commit:8330c338b1 -- umorigu 2018-03-23 (金) 01:47:32

関連


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-03-23 (金) 01:59:29
Site admin: PukiWiki Development Team

PukiWiki 1.5.1+ © 2001-2016 PukiWiki Development Team. Powered by PHP 5.6.38-0+deb8u1. HTML convert time: 0.321 sec.

OSDN