前回の日記で、コンテキストに応じたオートエスケープ機能をもつテンプレートエンジンに期待する旨を書いた。そうしたテンプレートエンジンは、すでにいくつも存在するが、メジャーにはなっていないようだ。少なくとも、Rubyではめぼしいものがなかった。
考えてみると、さまざまなコンテキストで動的に文字列を出力しようというのが無茶なのかもしれない。発想を変えて、HTMLエスケープのみで済むコンテキストにおいてだけ、動的出力を許すことにしてはどうか。
その前提からは、以下のコーディング規約が導き出せる。
- クライアントサイドのロジックは、関数呼び出しや値の代入部分も含め、すべて静的に書く
- クライアントサイドのロジックに渡したい値は、任意のHTML要素の属性値として出力する
URLの出力については、テンプレートエンジンのヘルパーメソッド経由でのみ許可するのが無難だろう。パーセントエンコーディング漏れがなくなるし、スキームのチェックもできる。
「結局、規約かよ」と思われるかもしれないが、「SQL文の実行にはプリペアド・ステートメントを使うべし」という話だって、つまりは規約の話なのだ。DOM Based XSS「対策」だって、エスケープ漏れを防ぐには、何らかの規約を設けるのが現実的だろう。
こう考えてくると、コンテキストに応じたオートエスケープ機能をもつテンプレートエンジンの必要性は薄くなる。メジャーになっていないのは、これが理由かもしれない。