安全なプラグイン用管理画面メモ

プラグインで管理画面を作る時に、ユーザにフォームに入力してもらったり、セレクトやラジオボタンなどで選択してもらってそれをデータベースに保存する時、色々なセキュリティ上の設定が必要ですが、それらについてメモします。

管理画面の作り方については、@lilyfanjpさんのこの記事にあるPDFが参考になります。

これを見ただけで僕が分からなかった部分については、@MakeGoodTimeさんに教わったりして、理解できましたので、ここで共有させてもらいます。

まずは、セレクトフォームの場合を用意して、のちのち数字、URL、メールアドレス、文字列、日付などを増やしていければと思います。

ここをコピペすれば最低限安心できる感じで。

例のフォーム

例として簡単なフォームを作ります。

</p>
<form action="" method="post">
<table>
<tr valign="top">
<th scope="row"><label for="xxx">果物</label></th>
<td>
<select name="fruits" id="fruits">
		<?php
		$select_options = array(
		array('value' => 'apple', 'text'=>'apple'),
		array('value' => 'banana', 'text'=>'banana'),
		array('value' => 'orange', 'text'=>'orange')
		);
		foreach ($select_options as $select_option) : ?></p>
<option value="<?php echo esc_attr($select_option['value']); ?>" <?php if(get_option('fruits') == $select_option['value']){ echo ' selected="selected"' } ?>><?php echo esc_attr($select_option['text']); ?></option>
<p>		<?php endforeach; ?>
	</select>
</td>
</tr>
</table>
<p class="submit"><input type="submit" name="Submit" class="button-primary" value="変更を保存" /></p>
<form>

これで、りんご、バナナ、オレンジから一つを選んでもらうフォームができます。actionは空、methodはpostです。htmlタグは、管理画面の他のページに合わせてます。

値を保存する方法

オプションテーブルに値を保存する場合は、セキュリティを無視すると以下。

update_option('fruits', '$_POST['fruits']');

POST値を受け取って、update_option()する。

入力された値を検証すると、以下。

$fruits = $_POST['fruits'];
if ( isset( $fruits ) && in_array( $fruits, array('apple', 'banana', 'orange' ) ) ) {
	update_option('fruits', $fruits);
}

とします。セレクトの場合は想定されているものが決まっているので、それ以外の可能性を全て排除しています。

wp_nonce_field()とcheck_admin_referer()

POSTの値が、本当にこの画面から送られてきているかを、WordPressに確認してもらうために、wp_nonce_field()check_admin_referer()を使います。

wp_nonce_field()の方を、formの中に書きます。
すると送信した時に、POSTに、_wp_http_referer_wpnonceが自動的に含まれます。

一方のcheck_admin_referer()は、update_optionなどその値をどこかに保存したり出力する、リスクが発生する処理の直前に設置します。

今回の例だと、下記のようになります。

<?php
$fruits = $_POST['fruits'];
if ( isset( $fruits ) && in_array( $fruits, array('apple', 'banana', 'orange' ) ) ) {
	check_admin_referer('example'); // ←ココと、
	update_option('fruits', $fruits);
}
?></p>
<form action="" method="post">
<table>
<tr valign="top">
<th scope="row"><label for="xxx">果物</label></th>
<td>
<select name="fruits" id="fruits">
		<?php
		$select_options = array(
		array('value' => 'apple', 'text'=>'apple'),
		array('value' => 'banana', 'text'=>'banana'),
		array('value' => 'orange', 'text'=>'orange')
		);
		foreach ($select_options as $select_option) : ?></p>
<option value="<?php echo esc_attr($select_option['value']); ?>" <?php if(get_option('fruits') == $select_option['value']){ echo ' selected="selected"' } ?>><?php echo esc_attr($select_option['text']); ?></option>
<p>		<?php endforeach; ?>
	</select>
</td>
</tr>
</table>
<p><?php wp_nonce_field('example'); // ココ。 ?> </p>
<p class="submit"><input type="submit" name="Submit" class="button-primary" value="変更を保存" /></p>
<form>

出力するときの注意

コデックスのデータ検証を参考にする。

文字列を出力する

	$text = get_option('the_key');
	$safe_text = esc_html($text);
	echo $safe_text;

esc_html関数

Encodes < > & ” ‘ (less than, greater than, ampersand, double quote, single quote). Will never double encode entities.

Always use when escaping user-input, in forms especially.

esc_htmlとesc_attrについて。

http://twitter.com/#!/lilyfanjp/status/125871165376954368

書きかけ。。。ここに出力時の注意を足していく。

↓ プラグインを作る方々への本、書きました。 ↓

“安全なプラグイン用管理画面メモ” への 3 件のフィードバック

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です