WebOS Goodies

WebOS の未来を模索する、ゲームプログラマあがりの Web 開発者のブログ。

WebOS Goodies へようこそ! WebOS はインターネットの未来形。あらゆる Web サイトが繋がり、共有し、協力して創り上げる、ひとつの巨大な情報システムです。そこでは、あらゆる情報がネットワーク上に蓄積され、我々はいつでも、どこからでも、多彩なデバイスを使ってそれらにアクセスできます。 WebOS Goodies は、さまざまな情報提供やツール開発を通して、そんな世界の実現に少しでも貢献するべく活動していきます。
Subscribe       

外部から渡されたエスケープ済みテキストを安全に表示する方法

本日は、codeなにがしウィジェットを作る過程で思いついた、ちょっとしたネタをご紹介。外部から API などで取得したテキストを安全に自サイトで表示するための Tips です。

codeなにがし API のレスポンスに含まれるデータは、ほとんどが HTML エスケープされた状態で渡されます。ですので、基本的にはそのまま HTML に挿入できます。これはこれで便利な仕様なのですが、外部から取得したテキストをノーガードで自サイトに含めるというのは、あまり気持ちのいいものではありませんよね。もし API 側にエスケープ漏れがあったら、こちらまで巻き添えをくうことになります。

この問題を解決する最もストレートな方法は、エスケープをいったん解除して、自力で再エスケープするというものです。しかし、 HTML の実体参照を完全に展開するのはなにげに厄介なので、もちっと簡単な方法を考えました。単に < > " だけをエスケープし、 & はそのまま残すという方法です。コードにすると以下のようになります。

function htmlescape(s)
{
  s = s.replace(/</g, '&lt;')
  s = s.replace(/>/g, '&gt;')
  s = s.replace(/"/g, '&quot;')
}

こうすると、もとから実体参照になっている文字は変化せず、生の < > " のみがエスケープされます。つまり、エスケープ漏れがあった場合のみ、それらを追加でエスケープするわけです。これは今回の目的にピッタリの動作ですね。

var s = '<div>foo</div>';
s = htmlescape(s);  // '&lt;div&gt;foo&lt;/div&gt;'
s = htmlescape(s);  // '&lt;div&gt;foo&lt;/div&gt;'(変化なし)

& がそのまま残るので(元テキストにエスケープ漏れがあった場合)実体参照が展開される可能性がありますが、それ以上の副作用はないはずです。スクリプト実行などを未然に防ぐのが目的であれば、じゅうぶんに役目を果たすでしょう。

ちなみに、実行例からもわかるとおり、上記の関数は何回かけても 2 重エスケープになりません。ですので、外部データであるかどうかに関わらず、最終出力の直前に必ず上記の関数を通すというのも悪くないかもしれません。

以上、本日は外部の API から取得した文字列を安全に表示するための簡易なエスケープ方法をご紹介しました。とくに JSONP で取得した外部データを表示する際に便利な方法だと思います。機会があれば、活用してみてください。

関連記事

この記事にコメントする

Recommendations
Books
「Closure Library」の入門書です。
詳しくはこちらの記事をどうぞ!
Categories
Recent Articles