最近の出来事ですので角が立ってはいけないのですが、安全なWebサイトを構築する上で重要なことですのでまとめておきたいと思います。
徳丸先生の『体系的に学ぶ 安全なWebアプリケーションの作り方 第2版』の4.3節「表示処理に伴う問題」にも書かれていますし、アルファサード社の野田さんもよく言われていますが、Webアプリケーション(CMS)でHTMLを生成する時はエスケープ処理を行うことが重要です。PowerCMSやMovable Typeだと<mt:Entry escape="html" />
のように必ずescape="html"
(もしくはencode_html="1"
)を付けてエスケープ処理を行います。WordPressだとesc_html()
を書きますね。
ただ、出力値に「文字参照(数値文字参照・文字実体参照)」が含まれると困ったことが起こります。例えばタイトル欄に®
と入力されている時、<mt:Entry escape="html" />
で出力すると&reg;
のように表示されてしまうからです。これがきっかけでescape="html"
をやめようか、という話になってしまうのです。
どのようにするのが良いのか?
実は話は単純で、文字コードにUnicodeを利用している環境においては、そもそも文字参照を利用しなくても良いという事実があります。『Google HTML/CSS Style Guide』の「3.1.6 Entity References」にも「Do not use entity references.
」とあります。
また、PowerCMSやMovable Typeに「®」の文字を入力して保存してみたのですが、問題なく保存・出力されます。
昔からWeb制作に携わっている方は長年の習慣で文字参照を使ってしまいがちですが(私もつい書いてしまうことがあります...)、キーボード入力やIMEの文字パレットなどを使い目的の文字をそのまま入力するようにしましょう。そうすればテンプレート職人は何のためらいもなく値のエスケープができる(escape="html"
が利用できる)のです。
CSVインポートには注意が必要
PowerCMSにはCSVインポート・エクスポート機能が備わっていますが、CSVを利用する際には文字化けに注意が必要です。ExcelもUTF-8に対応しているのですが、どうもBOM付でないと文字化けするようです。PowerCMSからUTF-8でエクスポートしたCSVにnkf --overwrite --oc=UTF-8-BOM [ファイル名]
でBOM付きにすると文字化けすることなく開くことができました。このようなこともあって無難に扱えるShift JISを使うこともありますが、Shift JISですと「®」の文字は利用することができません。®
と書いてインポートした後に「®」に置換するのが良いかなと考えています。
おまけ...esape="html"とescape="url"
Movable Typeにおいて、escape="html"
とescape="url"
のどちらを使うかも整理しておきたいと思います。
通常のテキストや属性値などにはescape="html"
を利用して< > " ' &
をエスケープします。URLだからといってescape="url"
を使うとおかしくなります。属性値はダブルクォートで囲みます。ちなみにWordPressの場合、a要素のhref属性はesc_url()
を使用してエスケープします。複数のCMSを扱う方はそれぞれのCMSの仕様を正しく把握しましょう。
<h1><mt:EntryTitle escape="html" /></h1>
<a href="<mt:EntryPermalink escape="html" />">
クエリストリングに記事タイトルを付ける等の場合はescape="url"
を使い、アルファベット以外の文字を16進数ベースの%xx
形式に変換します。(URLエンコード)
<a href="https://example.com/?q=<mt:EntryTitle escape="url" />">
ただ、お客様など詳しくない方はファイル名を日本語にされている場合があってどうしたものか...、と思います。