この記事はブロックされています。続きを読みたい方はログインをして下さい。会員ではない方は新規会員登録をして下さい。


ワードプレスでオリジナルプラグインを作ってみよう その5 セキュリティに考慮したプラグインの管理画面を作る

前回はプラグインの管理画面を作ってデータの呼び出しと保存をすることができました。
しかし、セキュリティに考慮していないため危険だということを説明しました。
今回はセキュリティに考慮した管理画面を作ってみます。

おさらいですが、前回はこんな感じで作りました。

//設定画面を表示する///////////////////////////////////////////////////////////
function my_mail_notice_set()
{

//キーを変数にセットして使い回す
$ID_KEY = 'target_id';
$ML_KEY = 'my_mail';

//フォームから渡された記事ID
$TARGET_ID = $_POST[ $ID_KEY  ];

//フォームから渡されたメールアドレス
$MY_MAIL = $_POST[ $ML_KEY ];

//IDとメールアドレスがあれば
if( $TARGET_ID and $MY_MAIL )
{
	//保存する
	update_option( $ID_KEY  , $TARGET_ID );
	update_option( $ML_KEY , $MY_MAIL );

	//メッセージを作る
	$msg = '<strong>保存しました。</strong>';

}
//なければ
else
{
	//wp_optionsから取得する
	$TARGET_ID 	= get_option( $ID_KEY  );
	$MY_MAIL 	= get_option( $ML_KEY );
}

//PHP終わり
?>

<div class="wrapper">

	<h2>基本設定</h2>
	<?php echo $msg; ?>
	<form action="" method="post">

	<table>
		<!-- 1行目 -->
		<tr>
			<!-- 1列目 -->
			<th>
				記事ID
			</th>

			<!-- 2列目 -->
			<td>
				<input name="target_id" type="text" size="30" value="<?php echo $TARGET_ID; ?>">
				<span class="notice">※ユーザーがアクセスしたら通知したい記事ID</span>
			</td>
		</tr>

		<!-- 2行目 -->
		<tr>
			<!-- 1列目 -->
			<th>
				メールアドレス
			</th>

			<!-- 2列目 -->
			<td>
				<input name="my_mail" type="text" size="30" value="<?php echo $MY_MAIL; ?>">
				<span class="notice">※自分に送信するメールアドレス</span>
			</td>
		</tr>

		<!-- 3行目 -->
		<tr>
			<!-- 1列目 -->
			<td colspan="2">
				<input type="submit" value="保存">
			</td>
		</tr>
	</table>

	</form>

</div>

<?php
//PHP始まり

}

まず最初のセキュリティですがリファラーをチェックします。
リファラーというのはどのページから実行されているかを保存している情報です。
リファラーはブラウザから取得できます。

このリファラーが管理画面のURLとは違うところから実行されていれば怪しいわけです。
なぜなら基本的にプラグインはワードプレスの管理画面を経由して実行されるからです。
この対策をしないとCSRF(クロス・サイト・リクエスト・フォージェリ)という攻撃を受ける可能性があります。

この攻撃方法は管理者権限でユーザーがログインしている時に、偽のリンクを踏ませることで管理者権限で意図しない操作を行わせます。

▼クロス・サイト・リクエスト・フォージェリ Wiki

リファラーをチェックするにはワードプレスに「check_admin_referer()」という関数が用意されています。

使い方は少なくとも「update_option()」を実行する前に記述します。

check_admin_referer( 'キー名' );

「キー名」なんですが、これは合言葉のようなものです。合言葉が符号すればOKというわけですね。
では、もうひとつの合言葉はどこに置くかというとフォームの中に入れておきます。
合言葉はフォームに含まれるので当然見ようと思えば見ることができるため、暗号化しておきます。
暗号化するには「wp_nonce_field()」という関数を使います。
キー名には「check_admin_referer()」と同じものを使います。

wp_nonce_field( 'キー名' );

次にフォームに入力した値が汚染されている場合があるので、エスケープします。
例えば、数字やメールアドレスといった特定文字列の入力を期待しているのに、HTMLタグやPHPのコードが入力されて乗っ取られる可能性があります。なのでフォームから受け取る値の種類が分かっていればチェックを入れます。
HTMLタグをエスケープ(別の文字列に置き換えること)するには以下のようにします。

$claen_string = esc_html( "<b>文字列</b>" );

もし半角数字だけであれば以下のように正規表現でチェックします。

if( preg_match( "/^[0-9]+$/" , $check_value ) )
{
	$value = $check_value;
}
else
{
	echo "半角数字以外が含まれています。";
}

もし半角英数字だけであれば以下のように正規表現でチェックします。

if( preg_match( "/^[a-zA-Z0-9]+$/" , $check_value ) )
{
	$value = $check_value;
}
else
{
	echo "半角英数字以外が含まれています。";
}

もしひらがなだけであれば以下のように正規表現でチェックします。

//正規表現の比較エンコードをUTF-8にする
mb_regex_encoding( "UTF-8" );
if( preg_match( "/^[ぁ-んー]+$/" , $check_value ) )
{
	$value = $check_value;
}
else
{
	echo "ひらがな以外が含まれています。";
}

もしカタカナだけであれば以下のように正規表現でチェックします。

//正規表現の比較エンコードをUTF-8にする
mb_regex_encoding( "UTF-8" );
if( preg_match( "/^[ァ-ヶー]+$/" , $check_value ) )
{
	$value = $check_value;
}
else
{
	echo "カタカナ以外が含まれています。";
}

もし漢字だけであれば以下のように正規表現でチェックします。

//正規表現の比較エンコードをUTF-8にする
mb_regex_encoding( "UTF-8" );
if( preg_match( "/^[一-龠]+$/" , $check_value ) )
{
	$value = $check_value;
}
else
{
	echo "漢字以外が含まれています。";
}

もし日本語だけであれば以下のように正規表現でチェックします。

//正規表現の比較エンコードをUTF-8にする
mb_regex_encoding( "UTF-8" );
if( preg_match( "/^[ぁ-んァ-ヶー一-龠]+$/" , $check_value ) )
{
	$value = $check_value;
}
else
{
	echo "日本語以外が含まれています。";
}

もし半角英数字、ひらがな、カタカナ、漢字、句読点、全角数字、改行だけ(記号不可)であれば以下のように正規表現でチェックします。

//正規表現のオプションに uオプションを付けて比較する
if( preg_match( "/^[ぁ-んァ-ヶーa-zA-Z0-9一-龠0-9、。nr]+$/u" , $check_value ) )
{
	$value = $check_value;
}
else
{
	echo "日本語以外が含まれています。";
}

もしメールアドレスの形式だけであれば以下のように正規表現でチェックします。

if( preg_match( '|^[0-9a-z_./?-]+@([0-9a-z-]+.)+[0-9a-z-]+$|' , $mail ) )
{
	$mail = $mail;
}
else
{
	echo "メールアドレスが不正です。";
}

といった感じで値が最初から決まっていれば誤入力を防ぐことが出来ます。

次にユーザー権限です。プラグインの設定は許可していなければ基本的に管理者だけがいじることができます。
管理者を判定するには「is_admin()」という関数を使います。管理者であれば真(True)を返します。
あるいは、ワードプレス登録ユーザーでかつ現在ログインしているユーザーに実行させるには「current_user_can()」関数でチェックします。

if( is_admin() )
{
	echo "管理者です。";
}
else
{
	echo "管理者ではありません。";
}
if( current_user_can( update_option( 'key' , '値' ) ) )
{
	echo "現在ログインしている登録ユーザーです。値を更新しました。";
}
else
{
	echo "登録ユーザーではありません。";
}

以上をまとめると以下のようになります。

関連記事