Ajax経由のデータ更新処理にはセキュリティ対策が必要
Nonce認証を追加する方法
WordPressのAjaxをよりセキュアにするための方法として、Nonce認証をAjaxの処理に追加することでセキュリティを高める方法がある。
WordPressでAjaxを利用するのエントリーでは、WordPressのAjaxインタフェースを利用すれば効率的に開発が進めるられることをコードを書きながら実践しつつ書いてみた。本記事では、そのコードにNonce認証を追加してセキュアにする。
実施する作業は以下のとおり
- wp_create_nonceでNonce tokenを生成
- check_ajax_refererでtokenの認証
実際に行う内容は上の2つのWordPress関数を利用してNonce認証を導入することになる。
wp_create_nonceで、各AjaxのリクエストURLに対して個別のNonce Tokenを生成する。そして、check_ajax_refererで、リクエストURLとtokenを基に認証を行い、invalid(無効)の場合には-1をレスポンスする。
wp_create_nonce
wp_create_nonce関連の処理部分にコメントを付加してみた。
function enqueue_script($hook) { if( !is_admin() ) { $hook = "public"; } wp_enqueue_script('ajax-script', plugins_url( '/js/ajax_requester.js', __FILE__ ), array('jquery') ); $ajax_nonce = wp_create_nonce("action_center-".$hook); // 各ページ毎に専用のNonce tokenを生成 wp_localize_script('ajax-script', 'ajax_object', array( 'ajax_url' => admin_url('admin-ajax.php'), 'action' => 'action_center', 'nonce' => $ajax_nonce, // Nonce tokenをグローバル化してajax_requester.js側で利用可能にする 'page' => $hook, 'param1' => "Hello Blog" ) ); }
Script要素が以下のように追加される。
<script type='text/javascript'> /* <![CDATA[ */ var ajax_object = {"ajax_url":"http:\/\/wordpress38ja2.local\/wp-admin\/admin-ajax.php","action":"action_center","nonce":"69c325ed03","page":"index.php","param1":"Hello Blog"}; /* ]]> */ </script>
フロント側のコードajax_requester.jsでnonceというデータを利用可能にする。
jQuery(document).ready(function($) { var data = { action: ajax_object.action, _security: ajax_object.nonce, // Ajaxリクエストの際に_securityというパラメータでサーバー側に送信される page: ajax_object.page, param1: ajax_object.param1 }; jQuery.ajax({ type: 'POST', data: data, url: ajax_object.ajax_url, dataType: 'json', success: function(response){ console.log(response); alert(response.page + ' is Ajax page'); } }); });
jQuery側には、nonceのtokenデータがサーバ側に送信されるように追加した。_securityという引数名を付けている点がポイントとなるが、引数名を_ajax_nonceとした場合には、check_ajax_refererの第2引数が不要となる点も補足しておく。
check_ajax_refererでtokenの認証
action_center_callbackにNonce tokenの認証処理を追加したのが以下の状態。WordPressの管理画面の各ページで個別にAjaxリクエストの認証処理が行われる。
function action_center_callback() { check_ajax_referer('action_center-'.$_POST['page'], '_security'); // 第2引数として_securityを指定し$_POST['_security']を利用 $param = $_POST['param1']; $param .= " World"; $data = array('param' => $param, 'page' => $_POST['page']); echo json_encode($data); die(); }
Ajaxリクエストをページ間で共通のURLとする場合は、
check_ajax_referer('action_center, '_security');
などとする。
実行結果とAjaxリクエストの様子は上の画像のようになる。
wp-config.phpのセキュア設定
WordPressのルートに配置されている
wp-config.php
でNONCE_KEYなどのランダム値を設定し、よりセキュアな状態でNonce認証を利用したい。
ランダム値は、WordPressの秘密鍵生成サービスを利用して効率的に作成することが可能。