PowerCMS X ブログ

2021-05-19

モディファイア「escape」の指定ルール

グローバルモディファイア「escape」は利用する頻度の高いモディファイアだと思いますが、どのようなケースで指定すべきかの考え方を纏めました。適切に指定しなければ脆弱性に繋がるケースもありますし、HTMLを壊してしまう可能性もあります。ビュー ( テンプレート・タグ ) を書くことのある人は是非ご一読いただき、理解いただくことをお勧めします。

escape 値をHTMLエンティティに変換またはその他の形式にエンコードします。 'html', 'xml', 'js', 'json', 'json_unescaped_unicode', 'php', 'url', 'single'(既存のHTMLエンティティをエンコードしない)のいずれかで、省略した場合は特殊文字がHTMLエンティティに変換されます

属性値を指定しない場合、もしくは'html', 'single'を指定した場合は、以下のルールで変換を行います。

変換前 変換後
& (アンパサンド) &
" (ダブルクォート) "
< (小なり) &lt;
> (大なり) &gt;

既存の HTMLエンティティを二重にエスケープしたくない場合は、escape="single" が指定できます。尚、PowerCMSでは escape="html" となり属性値は省略できないので違いに注意してください。

PowerCMS Xには「encode_html」モディファイアがありません。次のバージョンで追加されます。

原則・escapeモディファイアを利用する箇所と指定の順番に関する注意点

グローバルモディファイアは複数指定できます(ただし、同じグローバルモディファイアを1つのタグの中には指定できません)。グローバルモディファイアは左から順番に適用されます。よって、以下の例では意図通りエスケープされません。

<mt:entrytitle setvar="title" escape>
<mt:var name="title">

以下のようにする必要があります(ただし、このような指定では見通しが悪くなりがちで、エスケープ指定しているのかしていないのかがわかりにくくなります)。

<mt:entrytitle escape setvar="title">
<mt:var name="title">

よって、「escapeモディファイアは、出力する箇所で指定するのが原則である」と覚えておいてください。

<mt:entrytitle setvar="title">
<mt:var name="title" escape>

1. (重要) ダイナミック・パブリッシングでユーザーがパラメタに渡した文字列を出力する箇所で指定する

ダイナミックパブリッシング (検索ページやフォームの確認画面など) で <mt:var name="request.パラメタ名"> とすることで、URLパラメタや POSTされた値を出力することができます。このタグをダイナミック・パブリッシング(動的生成)で出力する HTMLページに利用する場合は、必ず escapeを指定してください。指定しなければ、XSS ( クロスサイトスクリプティング ) の脆弱性に繋がります。

  • ダイナミック・パブリッシング内でパラメタを出力する箇所 ( 「<mt:var name="request.query" escape>」の検索結果 )

<mt:var name="request.パラメタ名">に escapeモディファイアを付けないで構わない唯一の例外は、メールテンプレート (HTMLメールを除く) の中でこのタグを利用する場合だけです。

2. HTMLタグを置くことのできない箇所で指定する

title要素や属性値の中など、HTMLタグを置くことのできない箇所にテンプレート・タグを書く場合は必ず指定すると覚えておくと良いと思います。remove_htmlをあわせて指定しても良いと思いますが、「>」のみを単独で利用している文字列を出力する場合などはそのまま出てしまう可能性がありますので escape モディファイアの指定は必須です。

  • title要素の中 (<title><mt:entrytitle escape> | <mt:websitename escape></title>)
  • 属性値の中 (<img src="<mt:assetfileurl escape="url">" alt="<mt:assetlabel escape>"> , <meta property="og:description" content="<mt:entrytitle escape>">)

3. JavaScriptコードやJSONテキストの中で指定する

「"」などがそのまま出力されることによってスクリプトやJSONが壊れてしまう可能性のある箇所に指定します。

  • JavaScript内の文字列 ( var title = "<mt:entrytitle escape="js">"; / var title = "<mt:entrytitle escape>"; )
  • JSON内の文字列 ( {"title" : "<mt:entrytitle escape="json">"} / {"title" : "<mt:entrytitle escape="json_unescaped_unicode">"} )

4. URLパラメタに渡す文字列に対して指定する

  • href属性の中 ( <a href="/search.html?tag=<mt:tagname escape="url">"><mt:tagname escape></a> )

escape="url" に代わりに encode_url モディファイアを指定することでも同様の結果が得られます。

5. RSSやXMLサイトマップなどのXMLの中で指定する

  • XMLの中 ( <title><mt:entrytitle escape="xml"></title> )

escape="xml" に代わりに encode_xml モディファイアを指定することでも同様の結果が得られます。encode_xml="cdata" とすることでエスケープせずに CDATAセクションとして出力することもできます。

6. PHPコードの中で指定する

PHPコードの中にテンプレート・タグを出力するようなケースでは、ビューの書き方によってはセキュリティのリスクに繋がる可能性があります。以下の例では記事のタイトルに「'」(シングルコーテーション)を入力するとPHPがコンパイルエラーとなり、「';」を入力すると、その後に入力した任意のPHPコードを実行できてしまいます。必ず escape="php" を指定するか、encode_phpモディファイアを指定することでも同様の結果が得られます。

  • PHPコードの中 ( <?php $str = '<mt:entrytitle escape="php">'; ?> )

カテゴリー:テンプレート作成Tips | 技術情報

投稿者:Junnama Noda

ブログ内検索

アーカイブ