Contents
はじめに
WordPressでカスタマイズをするとき、フォームからデータを保存する処理を書いたことがあると思います。
でも、セキュリティのチェックを忘れていると、悪い人にサイトを勝手に操作される危険があります。
日頃からチャットGPTに何でも話しかけているんですが、ある時、自分のワードプレスのサイトのコードを見てもらったところ「脆弱性がある」と教えてもらったんです。その時に修正手続きを行ったんですが、気になったのがタイトルのワード。
そのセキュリティのために使われるのが wp_verify_nonce()
です。
🧠 wp_verify_nonceってなに?(小学生でもわかる説明)
これは「このフォーム、本当にこのサイトから送られたものかな?」って確かめる合言葉チェックです。
例えると…
- お母さん(=フォーム送信)から買い物メモ(=データ)が届いたとします。
- でも、それが本当にお母さんが書いたかわからなかったら危ないですよね。
- そこで「合言葉(=nonce)」を入れてもらいます。
お母さんが言った「今日の合言葉は “りんごジュース”」
あなたは受け取ったときに「“りんごジュース”って書いてあるな。OK、本物だ!」ってわかります。
それが wp_verify_nonce()
の役目です。
💥 実際の失敗例(コード)
❌ 修正前のコード
phpコピーする編集する$my_nonce = isset( $_POST['st_kanri'] ) ? $_POST['st_kanri'] : null;
if ( ! wp_verify_nonce( $my_nonce, wp_create_nonce( __FILE__ ) ) ) {
return $post_id;
}
🔥 なにがダメ?
wp_create_nonce()
は毎回違う文字列を作るので、
チェックするたびに新しい合言葉を作ってしまって、絶対に一致しないのです。
→ どんなに正しく送っても、保存できない or 無視される
✅ 修正後の正しいコード
✔️ フォーム側(nonceの埋め込み)
phpコピーする編集するwp_nonce_field( __FILE__, 'st_kanri' );
✔️ 保存処理側(nonceの確認)
phpコピーする編集する$my_nonce = isset( $_POST['st_kanri'] ) ? $_POST['st_kanri'] : null;
if ( ! wp_verify_nonce( $my_nonce, __FILE__ ) ) {
return $post_id;
}
🔁 修正前後の動作比較
項目 | 修正前 | 修正後 |
---|---|---|
保存成功 | ❌ 常に失敗 | ✅ 有効なときだけ成功 |
セキュリティ | ⚠️ 無効 | ✅ 十分 |
エラー発生 | 投稿保存されない | 正常保存 |
再現性 | 毎回違う | 毎回一致 |
💡 なぜこのチェックが重要?
WordPressの管理画面はログインしていればいろんな操作ができます。
でも、外部の誰かが勝手にフォームを送ってきたら…?
それを防ぐために「nonceチェック」があるんです。
つまり、悪意ある攻撃(CSRF)を防ぐための最後の砦になります。
🛠 AFFINGERでの実装ポイントまとめ
- 保存処理に
wp_verify_nonce()
を必ず入れる wp_create_nonce()
は使わず、フォームと確認で**同じ文字列(例:__FILE__
)**を使うwp_nonce_field()
をフォームHTML内に追加する- 保存側の
save_post
アクションに正しくフックする
🎁 おまけ:コピペ用テンプレ
フォームに入れる
phpコピーする編集するwp_nonce_field( __FILE__, 'st_kanri' );
保存処理に入れる
phpコピーする編集する$my_nonce = isset( $_POST['st_kanri'] ) ? $_POST['st_kanri'] : null;
if ( ! wp_verify_nonce( $my_nonce, __FILE__ ) ) {
return $post_id;
}
それにしても、なぜこんなエラーが起きたんだろう。変なところはいじってない
ChatGPT:
とても自然な疑問です。実はこのタイプのエラー(wp_verify_nonce()
の比較ミス)は、「書き方の意味を誤解してしまいやすい」ことが原因で、以下のようなケースでよく起きます:
🔍 なぜエラーが起きたのか?主な原因4つ
- 公式のドキュメントやチュートリアルが分かりづらい
wp_create_nonce()
をフォームに出力する用として書いてあるのに、初心者には「それで比較していい」と思い込んでしまう。
- 似た関数名で混乱
wp_create_nonce()
(合言葉を作る)wp_verify_nonce()
(合言葉が正しいか確認)
というペアで使うのに、実際の比較対象として使うのはNG。これが紛らわしい。
- カスタムテーマの構造が複雑
- 特にAFFINGERなどの高機能テーマでは、管理画面が独自構造になっていて、どこにnonceを入れるべきかが分かりづらい。
- もともと開発者が間違えて書いていた可能性もある
- もとのコードがコピペ元などから引き継いだ「そもそも正しくない記述」のまま放置されていた可能性も高いです。
💡だから自分が悪いわけじゃない
あなたのように「変なところをいじってない」のにバグに出くわした場合、
テーマ製作者側が見落としたロジックミスが残っていたケースも多く、
それを今回たまたま保存処理で踏んだ、という可能性が大です。
🤷♀️「いじくった覚えはない」──ではなぜエラーが?
実際、今回のようなwp_verify_nonce()
のミスはテーマやプラグインのバージョンに依存していたり、過去の仕様変更に気づかず放置されていたケースでよく起きます。
📌 よくある原因
原因 | 詳細 |
---|---|
🔧 テーマ側の初期コードミス | 最初から wp_create_nonce() を比較対象にしていた誤実装が存在する。古いテーマにありがち。 |
🌀 自動更新時のコード破損 | サーバーやFTP更新のタイミングで、変更済みファイルが書き戻された可能性。 |
📂 テーマ子ファイルへの影響 | 子テーマにカスタマイズがあり、親テーマの挙動が正しく継承されていないことも。 |
🛠 カスタマイズ作業時の混入 | 過去に外注や自作でカスタマイズしたコードが、時間を経て影響していた可能性も。 |
🧭 対処のポイント
- 過去に追加・上書きされたコードをGitなどで記録しておくと、原因追跡が簡単になります。
- 子テーマの関数を疑うことも重要です(
functions.php
に上書き処理がないか確認)。 - テーマ・プラグインの公式アップデート履歴(changelog)を見るのも有効。
📘 WordPressセキュリティ強化ガイドを読もう
nonceの役割を正しく理解するには、公式ガイドや専門解説記事がとても参考になります。
🔗 参考リンク
- 🔐 WordPress公式 Codex: Nonces の説明
- 🧠 WordPress 日本語公式: セキュリティ基本
- 📘 Digging Into WordPress: Understanding Nonces
こうしたガイドを一読することで、今回のようなnonceの使い方やWordPress全体のセキュリティ設計がクリアになります。
✅ 記事全体まとめとしてのタイトル案
- 「WordPressでよくあるwp_verify_nonceミスとその対処法」
- 「テーマに潜むセキュリティ穴を見逃すな!nonceの正しい使い方」
- 「いじった覚えがなくても危険?WordPressフォームの合言葉エラー解説」
✍️ まとめ
wp_verify_nonce()
を正しく使わないと、
保存できないだけでなく、セキュリティの穴にもなります。
自分のフォームで「チェック入れてたっけ?」と思ったら、今すぐ確認しましょう!