この記事は最後に更新してから1年以上経過しています。

フォーム内のエスケープ処理を考える

説明

WordPressにはエスケープ処理を行う esc_html関数と esc_attr関数がある。HTML要素(タグ)の属性値ならesc_attr関数を、それ以外はesc_html関数を使うことがほとんどだが、今回esc_html関数が適していないと思われるケースに遭遇した。

HTMLエンティティを含んだ文章をそのまま保持したい

これまで何等かの文章を編集するフォームを作る場合、TEXTAREA要素を使い、文章部分はクロスサイトスクリプティング(XSS)の要因にならないようesc_html関数でエスケープ処理したものを表示していた。

<textarea name="content"><?php echo esc_html( $content ); ?></textarea>

いつもならこれで問題なかったのだが、文章部分にHTMLエンティティを含む場合はそのHTMLエンティティが見た目上は実体になってしまう。例えば上記の$contentの内容が'©'の場合、esc_html関数は'&'を'&amp;'には変換されず、上記のコードは次のように出力される。

<textarea name="content">&copy;</textarea>

仮にこの内容を変更せずにサブミットすると、$_RQUEST['content']の内容は©(UTF-8: 0xC2A9)になってしまい、HTMLエンティティを保持する場合は何等かの前処理が必要になる。

esc_html関数の機能

これまで何気なく使ってきたesc_html関数だが、esc_html関数とPHPのhtmlspecialchars関数(ENT_QUOTESを指定)を比較し、機能を再確認することにした。次の表が2つの関数の返り値の違いとなる。

入力パラメータesc_html関数htmlspecialchars関数
&&amp;&amp;
<&lt;&lt;
>&gt;&gt;
"&quot;&quot;
'''
&lt;&lt;&amp;lt;
&copy;&copy;&amp;copy;
&rsquo;&rsquo;&amp;rsquo;
&amp;#8217;
&amp;#008220;

2つの関数とも上側の5文字はエスケープ処理されるが、下側のHTMLエンティティについてはesc_html関数の方はエスケープ処理されず、htmlspecialchars関数の方はエスケープ処理されるところが大きな違いである。またesc_html関数ではHTMLエンティティに対して余分な0を取り除いている。

今回はhtmlspecialchars関数を使う

TEXTAREA要素の内容や文字を扱うINPUT要素のvalue属性にはHTMLエンティティが含まれる場合があり、それらに変数の内容を設定する際はHTMLエンティティがエスケープ処理されないesc_html関数は適していない場合がある。今作っているプラグインのフォーム内では、HTML要素やHTMLエンティティを含んだ文字列を扱い、HTMLエンティティは常に維持しておきたいため、エスケープ処理はhtmlspecialchars関数を使うことにした。


最終更新 : 2018年10月19日 16:39


お勧め

wp_save_post_revision(2024年1月10日 更新)

int | WP_Error | void wp_save_post_revision( int $post_id )
現状の投稿のリビジョンを作成する。

get_the_author_posts_link(2019年8月21日 更新)

string get_the_author_posts_link( )
投稿者アーカイブページのリンクを取得する。

get_year_link(2012年2月2日 更新)

string get_year_link( mixed $year )
年アーカイブのURLを取得する。

register_taxonomy(2022年6月1日 更新)

WP_Taxonomy | WP_Error register_taxonomy( string $taxonomy, array | string $object_type, array | string $args = array() )
タクソノミーを登録する。

wp_add_object_terms(2013年8月6日 更新)

mixed wp_add_object_terms( int $object_id, mixed $terms, mixed $taxonomy )
投稿情報などにタクソノミーを追加する。