Preventing XSS with Data Binding. The PoC

PDFのUXSSなどの発見で有名なStefano Di Paola氏のPoCです。

現状の一般的なXSS対策とは異なり、バリデーションやHTMLエスケープ(バインド)処理を、ブラウザ側で行なおうというものです。

バインド処理

例えば、サーバからブラウザに以下のようなHTMLを返します。

<input type="text" name="yyy" bindattr="value=foo|">
.....
</html>
<plaintext style="display:none">
foo|こんにちは

変数はHTML末尾のplaintextタグ内に定義しておきます。onload時にJavaScriptで、plaintextタグ内の変数を読み取り、DOMを使ってinputのvalue属性にセットしてやります。

この他に、タグの内側のテキスト部分や、href/style属性、HTMLコメントに値をセットする方法が提供されています。

バリデーション処理

XSSを防ぐためにはバインド(エスケープ)だけでなく、バリデーションが必要な場合もあります。このPoCでは、ブラウザ側でhref/style属性をバリデートするJavaScriptコードも含まれています。

面白いのは、style属性のバリデーションの前処理です。

this._astyle = document.createElement('A');
this._astyle.style.cssText = sty;
  // left:e\xp/* */ression(alert(123))
sty = this._astyle.style.cssText;
  // left:expression(alert(123)) になる

攻撃者は通常、フィルタ処理を回避するためにstyle内の「expression」などに様々な仕掛けを施します。このPoCでは、バリデーションの前処理として、上のような感じのJavaScriptコード(実物はちょっと違いますが)によりstyle文字列を正規化しています。これによりバリデーションが容易になります。

このPoCの方式のメリット

Paola氏の方式のデメリットは、たくさん書かれているので(http://ha.ckers.org/blog/20070814/preventing-xss-using-data-binding/など)、ここではメリットについて書いてみます。

  • HTML部分は静的になる
    htmlの終了タグまでの部分は静的(ユーザからの入力データなどを含まないという意味)になります。plaintext内は動的に生成されますが、この部分のJavaScriptは実行されることはありません。
  • WebアプリケーションでHTMLエスケープする必要が無い
    plaintext内に定義する複数の変数は、改行文字で区切られます。改行文字のみエスケープが必要です。
  • バリデーションの精度
    ブラウザが正規化した後のデータに対して、styleやhref属性などのバリデーションを掛けることができます。ブラックリスト方式でも漏れがでる可能性が減るわけです。またこのPoCでは、styleとhref属性に値をセットする際に自動でバリデートされるようになっています。バリデーションの漏れが減らせるでしょう。
  • バインドの精度
    属性に値をセットする場合、不正な文字によって終端のダブルクォートを壊すような攻撃があります*1。Webアプリケーション側でのエスケープ処理では、この手の攻撃に脆弱な実装もあるのですが、このPoCの方式では安全です。

ただし現状のPoCの実装にはいくつかの穴があるようです。上記は原理上考えられるメリットと考えてください。

この方式の将来性

動的なSQL文の発行に際しては、バインド機構を使用することが常識になりつつあるように思います。それでは、HTMLにおいてもバインド機構の使用が進むのでしょうか。

結論から言うと、私は余りこのような仕組みは浸透しないと思います。この方式には多くのデメリットがあるからです。例えば、JavaScriptが無効だと動作しない、load完了まではデータがバインドされないなどのデメリットです。さらに、Webアプリケーション側のテンプレートエンジンの処理などでも基本的には同じようなことができるからです。

Paola氏は、将来的にはブラウザがDMBSのようにバインド機能を提供することを想定しているようです。そうなった時には、上記のようなデメリットは解消され、また変数データとテンプレートの分離方法はよりスマートになり、両者を統合するJavaScriptコードをわざわざ記述する必要もなくなるかもしれません。

しかし、ブラウザがそのような機能を導入する可能性も低いと思います。というのは、SQLのprepared statementを利用したバインド機構には、SQL文のParseコスト削減による性能向上という、他の方法では代替できない強力なメリットがあるのに対して、このPoCの方式にはそのような「代替がきかない強力なメリット」が無いからです。

*1:IEでは、EUC-JPの補助漢字(例えば「彅(8FBCF4)」)を用いても同様のXSS攻撃が可能です。