今回の記事では、WordPress のテーマ開発にしぼって、安全なテーマを開発するためのポイントについて説明します。
現在この記事の著者は、WordPress の公式テーマディレクトリのテーマレビューの自動化に取り組んでいて、実際のテーマレビューの経験もあります。
その経験をもとに、これがやられてないと確実に突きかえすでっていう内容を書いていきます。
想定読者
この記事が想定している読者は、WordPress のテーマを仕事でつくっているけど、プログラミングの知識があまりなくて自信がないという方です。
WordPress のテーマ開発で重要なのはとにかくエスケープすること
以下で紹介することを確実に守れば、みなさんが作るテーマに脆弱性がまぎれこむ可能性がとても低くなります。
意外と簡単なので、ぜひ覚えておくといいと思います。
the_* 関数を使う
テーマの中で、タイトルや本文、その他なんらかの出力を行う場合には、かならず the_* 関数を使用しましょう。
たまにブログ等で、以下のような記述を見かけますがこれは誤りです。
echo get_the_title(); // これは誤り
正しくは以下の通りであるべきです。
the_title();
さらに言うなら、WordPress コミュニティではテンプレートタグという表現で PHP のコードと安全に使える関数を区別していますので、なるべく以下のようにブログ等では紹介してくれるとありがたいです。
<?php the_title(); ?>
https://codex.wordpress.org/Template_Tags
これらの the_*
関数は、すべて適切にエスケープされていますので、セキュリティに関する知識がなくても安全に使用することができます。
その他のテンプレートタグ
WordPress の関数の中には、echo
とか print
とか書かなくても出力をする関数があります。
bloginfo()
wp_enqueue_script()
wp_enqueue_style()
wp_head()
body_class()
wp_nav_menu()
dynamic_sidebar()
wp_footer()
思いついたものを適当に書いただけなのでこれら以外にもあると思いますが、それらの関数は、セキュリティについて特に意識しなくても安全です。
print や echo を使用する場合
テーマの中でどうしても echo を記述したい時は、以下のように記述しましょう。
実はバリエーションはそれほど多くはありません。
テキストを出力をしたい
たとえば、HTML の中に安全なテキストを出力したい場合は、以下のように esc_html()
を使用してください。
<div><?php echo esc_html( $string ); ?></div>
こうすると HTML がエスケープされますので、意図しない JavaScript や HTML を防ぐことができます。
テキストエリアの中に安全なテキストを出力したい
<textarea />
の中に安全なテキストを出力したい場合は、esc_textarea()
を使用してください。
<textarea><?php echo esc_textarea( $string ); ?></textarea>
HTML の属性の値に安全な文字列を出力したい
たとえば、<div class=””> みたいな HTML の属性に安全な テキストを出力したい場合には、以下のように esc_attr()
を使うべきです。
<div class="<?php echo esc_attr( $string ); ?>">
URL を出力する
これは多くの場合 HTML の属性に出力する場合に使用されますが、なんらかの URL を出力する場合には、以下のように esc_url()
を使用するべきです。
<a href="<?php echo esc_url( $url ); ?">
URL は、http://
や https://
に限らず以下リンクのプロトコルも同様に記述されるべきです。
https://developer.wordpress.org/reference/functions/wp_allowed_protocols/
たとえばメールなら以下のように記述してください。
<a href="<?php echo esc_url( 'mailto:' . $email ); ?">
HTML を出力したい
たとえばなんらかの HTML をフォームで入力してもらってそれを出力したい場合、以下のように使用可能な HTML を制限することができます。
$allowed_html = array( "a" => array( "href" => array(), "title" => array(), ), 'br' => array(), 'em' => array(), 'strong' => array(), ); $allowed_protocols = array( 'http', 'https' ); echo wp_kses( $html, $allowed_html );
上の例では、$allowd_html
で許可される HTML 要素、$allowed_protocols
でリンクに使用可能なプロトコルを指定しており、これらにマッチしない文字列は取り除かれて出力されます。
公式テーマのレビューでは、このフィルターを通さずになんでもかんでも出力するというのは認められません。
カスタマイズ性が高いテーマをつくる際の注意
たとえば管理画面から背景画像やヘッダー画像を変更できるようにしたいなど、なんらかのカスタマイズ機能を提供したい場合には、add_theme_support()
を使用する必要があります。
この場合、functions.php
とか header.php
等にいろいろ書く必要がありますが、上述した内容がきちんと守られていれば脆弱性が混入する可能性を限りなくゼロに近づけることが可能です。
問題なのは、完全に独自の設定画面を設けることで、これはセキュリティ上のリスクだけでなく互換性のトラブルを招くリスクも高まります。
汎用的につくってテーマディレクトリ等で公開するなら、独自の管理画面を実装しても多くの目があるため問題を早めに察知できるかもしれませんが、そうでない場合は独自の管理画面を設けるべきではありません。
現在の公式テーマディレクトリでは修正を求められる可能性が非常に高くなります。