nonce ってナンスか?
春だというのに寒いですねぇw
それはさておき、みなさんは nonce という言葉を聞いたことがあるでしょうか? 日本ではあまり馴染みがないように思いますが、コンピュータ (というか暗号) の世界では一度だけ使われる使い捨てのユニークな数 (英語版 Wikipedia の説明) のことを言います。
WordPress には CSRF 対策として nonce という機能が実装されています。 wp_create_nonce で nonce を生成し、wp_verify_nonce でこれを検証することができます。 リンク先の Codex にも例がありますが、wp_create_nonce で生成した nonce を HTML のフォームに埋め込み、サーバーで受けたその値を wp_verify_nonce で検証する、というような使い方ができます。
ただし、注意点が一つあります。 WordPress の nonce は本来の意味の nonce とは異なり、ワンタイムの使い捨てというわけではありません。 12時間ごとに変更され、検証に際しては 24時間有効です。 もっとも CSRF 対策として考えたとき、ワンタイムである必要はありません (例えば高木先生の記事)。 推測されないようにきちんとランダムであれば、そして有効期間が適切であれば CSRF 対策として十分です。
wp_verify_nonce は、現在の nonce の値と同じならば 1、1つ前の nonce と同じならば 2を返します。 つまりデフォルトでは 0-12時間で 1、12-24時間で 2が返されることになります (時間の数え方は後述)。 nonce が一致しなければ wp_verify_nonce は 0を返すので、通常はこれをそのまま真偽判定条件式として使用します。
有効期間の短縮
その有効期間ですが、デフォルトの 24時間を短縮したいときは add_filter することで変えられます。
add_filter( 'nonce_life', 'my_nonce_life' ); function my_nonce_life() { return 3600; /* 1 hour */ }
このテクニックはテスト時にも使えそうですね。
なお、この有効期間は wp_create_nonce を呼んだ時からカウントダウンが始まるわけではなく、time() の値を使って周期的に変えているだけなので、ちょうど変わり目 (GMT の 0時とか 12時とか) にあたると短時間で値が変化することになります。 それでも先述の通り一つ前の nonce まで有効と判定されるので通常は問題ないでしょう。
nonce の素
さて、この nonce ですが、以下の情報を元に生成されます。
- ユーザー ID
- 時刻 (といっても 12時間単位)
- wp_create_nonce に渡された引数 $action
- サイト毎に持っている秘密キーと Salt
これらが同一であれば同じ値になります。 ここで開発者にとって気になるのは 4. の秘密キーと Salt ではないでしょうか? そして自分の wp-config.php に以下のような記述を見つけて焦るわけです。
define('AUTH_KEY', 'put your unique phrase here'); define('SECURE_AUTH_KEY', 'put your unique phrase here'); define('LOGGED_IN_KEY', 'put your unique phrase here'); define('NONCE_KEY', 'put your unique phrase here'); define('AUTH_SALT', 'put your unique phrase here'); define('SECURE_AUTH_SALT', 'put your unique phrase here'); define('LOGGED_IN_SALT', 'put your unique phrase here'); define('NONCE_SALT', 'put your unique phrase here');
これを見ると「げっ、ウチのサイト、ヤバい??!」と思ってしまいますよね。
でも、安心してください。 実はこのような wp-config.php となっている場合は、自動的に秘密キーと Salt を生成してデータベースに保存し、それを使ってくれます。 このままでも「put your unique phrase here」をキーとして使うことにはなりません。
となると wp-config.php を書き換えたくなるのは定期的にキーを変更したい場合ぐらいでしょうか。 生成には https://api.wordpress.org/secret-key/1.1/salt/ を使いましょう。
学習のために
興味のある人は wp-include/pluggable.php の nonce 関連関数を読んでみましょう。
私が WordPress の nonce について知ったのは「Professional WordPress Plugin Development」という書籍によってです。 この書籍は WordPress のプラグイン開発に必要な情報が一通りまとまっており、分量も重くないのでお勧めです。 英語も難しくないですし。
英語ついでですが、こちらの WordPress の nonce についての記事も参考情報として挙げておきます。
2013.4.17 追記
nonce の変わり目の際の動作について訂正。(一つ前の値も有効なので変化してもすぐに verify エラーになるわけではない)