【WordPress】自作プラグインに導入しておきたいカスタム関数のコード集 vol.1【セキュリティ対策重視】

シェアする

wordpress-logo

前項でWordPress(ワードプレス)をカスタマイズするにあたって、カスタム関数(ユーザー定義関数)のコードを自作プラグインで一元管理する方法を紹介し終えました。

そこで、今後は有用なコードを『WPカスタマイズコード』シリーズとしてご紹介して参りたいと思います。

なおこのシリーズでは、各コードの用途などを記した簡単な解説を付けるように心掛けて参りますが、コメントアウトに引用元ないし参考元のURLを併記しておりますので詳細などをご覧になりたい場合はそちらをご覧下さい。

先ずシリーズ第一弾となる本稿では、主にセキュリティ対策として導入しているコードをご紹介します。

スポンサーリンク

初期の段階で導入しておきたいコード集という位置付け

WordPressには初心者でも扱いやすいようにプリセットされた仕様に基づく初期設定がいくつか存在します。

しかし、それらはWordPressに使い慣れてくるとやがて利便性向上のために使用されなくなったり、セキュリティの観点から問題視されるようになります。

本稿では、初期の段階からでも導入しやすくてセキュリティ向上に貢献できるコードを取り揃えました。

URL/loginからのリダイレクトを無効にする方法

初期設定ではブログアドレス(簡単に言えばトップページのURL)の末尾に”/login”を付加して移動するとログイン画面にリダイレクトされます。

一見すると初心者にとっては便利な仕様ですが、悪意あるハッカー(クラッカー、ネットスパイ等と称される輩)がその方法でアクセスした場合には、ログイン画面のURL(wp-login.phpへのパス)がバレてしまい、ホームページの乗っ取りを目的としたブルートフォースアタック(総当たり攻撃)の格好の餌食となる危険性を併せ持ちます。

それ故に、ログイン画面のURLをブックマークしたら可及的速やかに無効にしておくべき不要な機能だと言えましょう。

/**
 * URL/loginからのリダイレクトを無効にする方法
 * http://www.rescuework.jp/blog/wp-login.html
*/
remove_action( 'template_redirect', 'wp_redirect_admin_locations', 1000 );

wp-includesのjQueryを消す方法&Google APIから読み込ませる方法

WordPressのwp-includesディレクトリにはjQuery(ジェイクエリー)のライブラリーがプリインストールされています。

ところが、同ディレクトリのjQueryを読み込んだ場合、デフォルトのおかしな仕様のせいでGoogle APIのjQueryを利用する仕様のプラグインが機能不全に陥る事案が報告されています。

また、自サーバーのjQueryのデータロードを要求させると、その分だけサーバー負荷が大きくなるためにページ全体の読み込み速度が遅くなります。

それ故、Google APIにあるjQueryライブラリー(平成28年7月時点での最新版は3.1.0)だけを読み込むように設定する事が望ましいでしょう。

/**
 * wp-includesのjQueryを消す方法&Google APIから読み込ませる方法
 * http://www.madeinthepain.com/wordpress-delete-wp-includes-jquery-and-load-googleapi/
 * Google Hosted Libraries(最新版のjQueryのURLが掲載されている)
 * https://developers.google.com/speed/libraries/#jquery
*/
wp_deregister_script( 'jquery' );
wp_enqueue_script('jquery','https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js');

wp_head()のいらないタグを削除してをスッキリさせる方法

WordPressのセキュリティ対策の基本は本体のプログラムやプラグインを速やかにアップデートする事であります。

ですが、プラグイン等の仕様によっては早々に更新できないサイトが存在するのも確かであり、その場合にはセキュリティーホールが発生します。

その未更新状態の間に悪意あるハッカーにセキュリティーホールの存在を気付かれないようにするための方法は、WordPressのバージョンを秘匿する事により、アップデートしているかどうかを判別不可能にさせてしまう方法が簡便です。

下記のコードはページのHTMLソース<head>~</head>タグ内に出力されるWordPressのバージョンを除去します。

(正確に言うとデフォで出力される前に阻止する処理)

/**
 * [WordPress]wp_head()のいらないタグを削除してをスッキリさせる方法
 * http://princesswell.rocketserver.jp/wordpress/wp_head-delete-waste/
*/
remove_action('wp_head', 'wp_generator');
remove_action('wp_head', 'rsd_link');
remove_action('wp_head', 'wlwmanifest_link');
remove_action('wp_head', 'wp_shortlink_wp_head');
remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
remove_action('wp_head', 'feed_links_extra', 3);

remove_action(‘wp_head’, ‘wp_generator’); では WordPress バージョンを隠し切れない

先述のコードだけでは、フィード(XML,RSS,Atomの類)に出力されるWordPressのバージョンの情報を非公開にする事が出来ません。

下記のコードはフィードへの出力を阻止できます。

/**
 * remove_action('wp_head', 'wp_generator'); では WordPress バージョンを隠し切れない
 * http://www.rescuework.jp/blog/wp_generator.html
*/
foreach ( array( 'rss2_head', 'commentsrss2_head', 'rss_head', 'rdf_header', 'atom_head', 'comments_atom_head', 'opml_head', 'app_head' ) as $action ) {
 remove_action( $action, 'the_generator' ); // フィード出力からもバージョン非表示にする
}
function remove_cssjs_ver( $src ) {
 if( !is_user_logged_in() && strpos( $src, '?ver=' ) )
 $src = remove_query_arg( 'ver', $src );
 return $src;
}
add_filter( 'style_loader_src', 'remove_cssjs_ver', 10, 2 );
add_filter( 'script_loader_src', 'remove_cssjs_ver', 10, 2 ); // CSS や JS のバージョンを取り除く

ログインしていない時のみattachment_id=ページに404を返す【アレンジドコード】

WordPressのメディアに画像ファイル等を保存した時、保存した個々のファイルのみを取り扱った『添付ファイルのページ』が生成されます。

添付ファイルのページはブログの本文中で使った画像のギャラリー等として機能しますが、そのURLは投稿記事や固定ページとは違って『ブログアドレス/?attachment_id=(数字)』というパターンになります。

http://www.example.com/?attachment_id=114514

末尾にあるattachment_id=の後に続く数字はアップロード順に割り当てられる通し番号であり、任意に変更することが出来ません。それは即ち、通し番号を総当りすればブログ上では公開していない添付ファイルにアクセスされてしまう恐れがある事を意味します。

下記のコードは、その対策として引用元にあった添付ファイルのページを404 Not Foundに差し替えて非公開にするコードに、is_user_logged_in()関数を追加してログインしていない場合だけ差し替えるようにアレンジしました。

/**
 * ログインしていない時のみattachment_id=ページに404を返す【アレンジドコード】
 * http://www.seotemplate.biz/blog/wordpress-tips/12786/
*/
function gs_attachment_template_redirect_kai() {
 if(!is_user_logged_in()){
 if ( is_attachment() ) { // 添付ファイルの個別ページなら
 global $wp_query;
 $wp_query->set_404();
 status_header(404);
 }
 }
}
add_action( 'template_redirect', 'gs_attachment_template_redirect_kai' );

画像挿入時の添付ファイルのページの選択肢を消す

デフォルトでは画像への直リンクの他に添付ファイルのページへのリンクを選択肢に加えています。

先述のように添付ファイルのページを非公開にしている場合、不要な選択肢である事は言うまでもありません。

下記のコードは、添付ファイルのページへのリンクを選択肢を除去する事で、誤って添付ファイルのページへのリンクを貼るリスクを無くす事ができます。

/**
 * 画像挿入時の添付ファイルのページの選択肢を消す
 * http://www.seotemplate.biz/blog/wordpress-tips/12786/
*/
function media_script_buffer_start() {
 ob_start();
}
add_action( 'post-upload-ui', 'media_script_buffer_start' );
 
function media_script_buffer_get() {
 $scripts = ob_get_clean();
 $scripts = preg_replace( '#<option value="post">.*?</option>#s', '', $scripts );
 echo $scripts;
}
add_action( 'print_media_templates', 'media_script_buffer_get' );

メディアファイルをアップロード時に自動的にランダムな名称に改称【アレンジドコード】

WordPressのメディアに画像ファイル等を保存した時、デフォルトではアップロードした際のファイル名がそのまま使用されます。

この時、ファイル名が日本語名等全角文字でも表示するだけなら問題はありませんし、同名で重複アップロードした場合でも自動的に名称の末尾にハイフンを挟んで通し番号が付加されるのでエラーを起こす心配はありません。

しかし、Gallery3の『画像のファイル名そのものをランダム化する』でも示したように、ファイル名が類推されやすい名称だった場合には未公開のファイルを閲覧される危険性があるため、やはりセキュリティ上好ましくありません。

したがって下記のコードは、アップロード時にメディアファイルの名称をランダムな半角英数の文字列を含むものに自動的に変更する機能を有します。

元はアップロード時にメディアファイルの名称をMD5ハッシュ化するだけだったものを、乱数文字列を混ぜてSHA1ハッシュ化し、類推不可能な名称に変更する仕様にしています。

加えて、アップロードディレクトリの中身を区別しやすいように、接頭辞と識別子をファイル名の頭に付加しております。

/**
 * メディアファイルをアップロード時に自動的に改称【アレンジドコード】
 * http://stackoverflow.com/questions/3259696/rename-files-during-upload-within-wordpress-backend
*/
function make_random_filename_hash($filename) {
 $info = pathinfo($filename); //ファイルのパスを取得
 $ext = empty($info['extension']) ? '' : '.' . $info['extension']; //ファイルの拡張子を取得
 $name = basename($filename, $ext); //ファイル名を取得
 $hashedname = sha1( $name ); //取得したファイル名をsha1でハッシュ化
 $randomletters = sha1( uniqid( mt_rand() , true ) ); //乱数文字列の生成
 $compound1 = $randomletters . $hashedname; //乱数文字列とハッシュ化したファイル名を連結
 $compound2 = sha1( $compound1 ); //合成文字列。連結した文字列を再度ハッシュ化して新たに文字列を合成
 $prefix = "att"; //接頭辞。uploadsディレクトリ内で添付ファイルである事を示すためのもの。
 $identifier = date('YW'); //識別子。アップロードした時期を特定するための数値。ここではdate関数で生成した6桁(西暦4桁+週番号2桁)の数値を採用
 $renewalname = $prefix . "-" . $identifier . "-" . $compound2; //更新名称。接頭辞と合成文字列との間にハイフンと識別子を挟ませて連結
 return $renewalname . $ext; //更新名称に拡張子を付加して出力
}
add_filter('sanitize_file_name', 'make_random_filename_hash', 10);

決定版!JetpackプラグインのOGPタグを削除する方法いろいろ

WordPress公式のJetpackプラグインを使用中でも、SMO用のOGPタグを独自に出力したいユーザー向けのJetpack機能制限用のコードです。

/**
 * 決定版!JetpackプラグインのOGPタグを削除する方法いろいろ
 * http://www.02320.net/remove_jetpack_ogp_tags/
*/
add_filter( 'jetpack_enable_open_graph', '__return_false' );
remove_action( 'wp_head', 'jetpack_og_tags' );

記事を公開する前に確認アラートを出す

下記のコードは、下書きの記事を誤って公開しないように確認アラートを出すものです。

/**
 * 記事を公開する前に確認アラートを出す
 * http://kachibito.net/wp-code/avoid-accidental-publishing
*/
$c_message = '記事を公開します。宜しいでしょうか?';
function confirm_publish(){
// JavaScriptを管理画面フッターに挿入する
global $c_message;
echo '<script type="text/javascript"><!--
var publish = document.getElementById("publish");
if (publish !== null) publish.onclick = function(){
 return confirm("'.$c_message.'");
};
// --></script>';
}
add_action('admin_footer', 'confirm_publish');