MENU

nonceチェックを入れたはいいが・・・

クロスサイトリクエストフォージェリ対策として、
メールフォームのチェックにnonceを設定しましょうね…というおすすめをみて実際実装したけども、
フツーに使う分には特に問題なかったのですが、
なぜか、WordPressの管理画面から表示したメールフォームだとエラーになってしまい…

なぜなのか…と思って、現在のnonceと送信されたnonceを表示させてみたところ、

【通常利用】
   送信されたnonce = ソース上の隠し要素nonce = チェックに使用されたnonce

【WordPressの管理画面から】
   送信されたnonce = ソース上の隠し要素nonce  チェックに使用されたnonce

でした。
ちなみに実装したソースは下記(チャッピーに作ってもらいました・・・🤖


// nonceを生成
add_action(‘wpcf7_form_hidden_fields’, function($hidden_fields) {
$nonce = wp_create_nonce(‘contact_form_nonce’);
$hidden_fields[‘contact_form_nonce’] = $nonce;
return $hidden_fields;
});

// 送信時、現在のnonceと送信データのnonceをチェック
function my_wpcf7_before_send_mail( $contact_form, &$abort, $mailobj ) {
// フォーム送信データのインスタンスを取得
$submission = WPCF7_Submission::get_instance();

if ($submission) {
// ユーザーが送信したデータを取得
$data = $submission->get_posted_data();

// サーバー側で生成された nonce を取得
$current_nonce = wp_create_nonce(‘contact_form_nonce’);

// 送信された nonce を取得
$submitted_nonce = isset($data[‘contact_form_nonce’]) ? $data[‘contact_form_nonce’] : null;

// nonce の確認
if ($submitted_nonce && wp_verify_nonce($submitted_nonce, ‘contact_form_nonce’)) {
error_log(‘Nonce is valid.’);
// 通常の処理
} else {
error_log(‘Invalid nonce or nonce is not set.’);

// 不正リクエスト時のメッセージを設定
$error_message = ‘不正なリクエストが検出されました。ページを開きなおしてもう一度お試しください。’
. ‘<br>現在の nonce: ‘ . esc_html($current_nonce)
. ‘<br>送信された nonce: ‘ . esc_html($submitted_nonce);

// フォームにエラーメッセージを設定
$mailobj->set_response($error_message);

// メール送信をスキップ
$abort = true;

// ログ出力
error_log(‘Abort set to true. Current nonce: ‘ . $current_nonce . ‘, Submitted nonce: ‘ . $submitted_nonce);
}
}
}

add_action(‘wpcf7_before_send_mail’, ‘my_wpcf7_before_send_mail’, 20, 3);

原因はよくわからず・・・
じっと手を見る・・・

まぁ、通常利用には影響ないからいっか・・・ということでクサフタしました・・・

一応チャッピーに聞いたところ下記の場合が考えられる模様(私は考えるのをやめましたが・・・

まとめ
通常、サーバーで生成された nonce と送信された nonce は同じ値であるべきですが、以下のケースでは異なる値が送信される可能性があります:
ページリロードやフォームの再送信
セッションの切れ
ユーザーがフォームを手動で改変
キャッシュされたページから送信
AJAX での非同期送信時の問題
これらの状況では、送信された nonce がサーバーで生成されたものと一致しなくなり、セキュリティ上のリスクとなる可能性があります。

目次