Google Crisis Response(Google)
災害に関する情報源や、行方不明者情報の収集と検索を行う『パーソンファインダー』を初めとするツールの提供が行われています。

2007年12月1日 土曜日

akismet-multibyteview のリンクの修正

Filed under: WordPress,ハック,プラグイン
時間:9時28分
投稿者:よしとも
AddClips 経由でソーシャルブックマークに登録

 WordPress のアップグレードと一緒に、そのままになっていた akismet-multibyteview のアップグレードもしました。1.20 からはダッシュボードのボックス枠(名前はあるんでしょうか。hook が activity_box_end なので、アクティビティーボックス?)にマルチバイトスパムの数が表示されるようになってさらに便利に。

 サイト内トラックバックが捕獲されてしまったので早速リンクから一覧に飛ぼうとしたのですが、File Not Found になってしまいました。ブラウザのアドレス覧を見ると http://edit-comments.php?page=akismet-admin&multibyte=true となっています。ソースコードでもやはりおかしなことに。

 こういうのを見るとついつい調べてみたくなります。早速ハックです。

ソースを見る

 何はともあれ、ソースコードを見ます。該当の処理は akismet-multibyteview.php の関数 akismet_stats_mbinfo が行っています。1.21 では139行目から始まっていて、目的の場所は156行目です。

  1. if ( $mbs_count ) {
  2.             echo
  3.                 '<li><a href="' . clean_url("{$this->akismet_admin_uri}&multibyte=true") .
  4.                 '"><strong>要チェック</strong></a>: スパムじゃないかもしれないコメントを ' .
  5.                 $mbs_count.' 件捕獲中です。</li>';
  6.         } else {
  7.             echo '<li>この中に日本語を含むものはありません。</li>';
  8.         }

 clean_url() という関数が使われています。URL として正しくなるように修正をするもので、WordPress ME2.1.3では wp-includes/formatting.php で次のように定義されていました。

  1. function clean_url( $url, $protocols = null ) {
  2.     if ('' == $url) return $url;
  3.     $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%]|i', '', $url);
  4.     $strip = array('%0d', '%0a');
  5.     $url = str_replace($strip, '', $url);
  6.     $url = str_replace(';//', '://', $url);
  7.     // Append http unless a relative link starting with / or a php file.
  8.     if ( strpos($url, '://') === false &&
  9.         substr( $url, 0, 1 ) != '/' && !preg_match('/^[a-z0-9]+?\.php/i', $url) )
  10.         $url = 'http://' . $url;
  11.    
  12.     $url = preg_replace('/&([^#])(?![a-z]{2,8};)/', '&#038;$1', $url);
  13.     if ( !is_array($protocols) )
  14.         $protocols = array('http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet');
  15.     if ( wp_kses_bad_protocol( $url, $protocols ) != $url )
  16.         return '';
  17.     return $url;
  18. }

 1078行目で、:// を含まなく / で始まっていなくて半角英数字+拡張子 php になっていない場合に http:// をつけるという処理をしています。

 そして、引数の文字列に含まれる変数 $this->akismet_admin_uri は、同じファイルの62行目で次のように定義されています。

  1. $this->akismet_admin_uri = 'edit-comments.php?page=akismet-admin';

 さて、ここで関数に渡される引数を確認してみます。変数が展開されると、引数は edit-comments.php?page=akismet-admin&multibyte=true となります。拡張子は php ですが、半角英数のファイル名ではありません。ハイフン(-)が入ってしまっています。そのため、clean_url() は http:// をつけてしまっていました。

 初めは akismet-multibyteview のバグだと思い解析をしていましたが、実は WordPress 側のバグでした。2.2.1 のコードでは次のように修正されています。

  1. if ( strpos($url, '://') === false &&
  2.         substr( $url, 0, 1 ) != '/' && !preg_match('/^[a-z0-9-]+?\.php/i', $url) )
  3.         $url = 'http://' . $url;

 作者のひろまささんはすでに2.3系になっていますので気が付かなかったのかもしれません。

修正

 コアファイルのほうを修正してもいいのですが、影響範囲が少ないプラグインのほうを直してしまいます。固定アドレスなので、関数の処理は必要ないと判断。156行目を次のように変更しました。ついでに & を文字参照にしてあります。やらなくても大丈夫ですが、気分的に。

  1. '<li><a href="' . "./{$this->akismet_admin_uri}&amp;multibyte=true" .

 これによってリンク先が正しくなり、マルチバイトスパムの一覧に飛ぶことができるようになりました。

Comments (1)

HTML convert time: 0.205 sec. Powered by

Images is enhanced with WordPress Lightbox JS by Zeo