DOM APIとinnerHTMLは等価ではない

Posted by Hiraku on 2011-06-05

最近、徳丸本をじわじわ読んでいるのですが、DOM based XSSの話が書いてあったので、少し言及しておこうと思います。

徳丸本から引用

DOM based XSSと呼ばれるXSSがあります。これは、JavaScriptによりクライアント側で表示処理する箇所があり、そこに脆弱性がある場合のXSSです。

サンプル書いてみました。

<script>
document.write(unescape(location.href));
</script>

こいつを適当なファイル名で保存して、domxss.html#<script>alert("hello")<script>などのURLでアクセスするとalertが表示されるはずです。任意のスクリプトが実行可能な状態ってことですね。任意のスクリプトが実行可能ってことは、セッションクッキー盗み放題で、他人に成り済まして買い物できちゃったりするレベルです。

悪いのはdocument.write()やinnerHTMLだ

例はかなりわざとらしいですが、document.write()innerHTMLといった、文字そのままを書き出すメソッドやプロパティを使うと、そこにDOM based XSSが可能になる余地が生まれます。
対策としてはhtmlをエスケープする、ちゃんとしたテンプレートエンジンを使う、ウェブ標準のDOM APIを使うなどが挙げられます。

DOMを使った対策例

DOMのAPIは適切なエスケープ処理を自動で行ってくれるため、XSSの対策になります。たとえばさっきの脆弱なコードはこんな風に書けばOK。

<script>
onload=function(){
  document.body.appendChild(document.createTextNode(location.href));
};
</script>

しかしinnerHTMLの方が人気者?

DOM vs innerHTML」でググると、パフォーマンスを比較する記事がたくさん見つかります。なかなか比較するのは難しいけれど、単純な性能で言えばinnerHTMLの方が速い傾向にあるらしいですね。

あとDOMのAPIは面倒くさいことが多いです。document.createElement()とかappendChild()しまくるよりは、innerHTMLで文字列連結しちゃった方が楽かもしれない。

なので、第三者の入力を受け付ける部分だけちゃんとDOMで書いて、外部入力の入り込む余地のない部分だけinnerHTMLで書く、ぐらいがよいと思います。

ただ、、、こういうinnerHTMLをばりばり使った記事が、未だに人気を集めるところを見ると、「DOMの書き換えはinnerHTMLを使って書くものなんですね!メモメモ〜☆」みたいな勘違いをする人が多そうで、今の状況は良くない気がしています。

言いたいこと

  • DOM APIとinnerHTMLは等価ではない。パフォーマンスだけで比較するのはナンセンス。
  • innerHTMLは危険な書き方である。何でもかんでもinnerHTMLを使うのはやめた方がいい。
  • JavaScriptにだってXSSを作り込む可能性がある。DOM based XSSはもう少し周知されるべき

もっと詳しく知りたい人は

DOM based XSSはここがかなり詳しい。英語だけど。
DOM based XSS Prevention Cheat Sheet - OWASP

冒頭の徳丸本ってのはこれのことね。サーバーサイドの話が多いけど、Web屋さんは知っておくべき内容。(DOM based XSSはp115の辺り)
体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践 [大型本] / 徳丸 浩 (著); ソフトバンククリエイティブ (刊)
体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践 [大型本] / 徳丸 浩 (著); ソフトバンククリエイティブ (刊)

ハイパフォーマンスJavaScriptにDOMとinnerHTMLの速度比較の記事が載ってた。(p37 3章のあたり)
ハイパフォーマンスJavaScript [大型本] / Nicholas C. Zakas (著); 水野 貴明 (翻訳); オライリージャパン (刊)
ハイパフォーマンスJavaScript [大型本] / Nicholas C. Zakas (著); 水野 貴明 (翻訳); オライリージャパン (刊)

innerHTMLを使わないDOMの参考図書。「DOM Scripting」的な名前の本ならあまりハズレはない気がする。私はこれで勉強しましたが、他にもいい本があるかもしれない。
Web標準テキスト(1) DOM Scripting (Web標準テキストシリーズ) [単行本(ソフトカバー)] / 古籏 一浩 (著); 技術評論社 (刊)
Web標準テキスト(1) DOM Scripting (Web標準テキストシリーズ) [単行本(ソフトカバー)] / 古籏 一浩 (著); 技術評論社 (刊)



keyword: javascript Security

JavaScriptの最新記事