E4X、連想配列とプロパティ、Object.evalメソッド
大垣さんのブログから
確かにかなり便利なのですが以下のコードでスクリプトが実行されることはほとんど知られていないでしょうね。
<script>
123[''+<_>ev</_>+<_>al</_>](''+<_>aler</_>+<_>t</_>+<_>(1)</_>);
</script>
このスクリプトの中には、興味深い要素がたくさん含まれていますが、説明もなく放り出されているので理解が難しいでしょうね。
E4Xについて
まず目につくのは、JavaScript(ECMAScript)のスクリプト中にXML形式でオブジェクト・リテラルを記述できるE4X(ECMAScript for XML)という機能です(FireFox1.5以降で対応)。これは、例えば以下のように使います。
var order = <order>
<name>Webアプリケーションのセキュリティ完全対策</name>
<author>徳丸浩他</author>
<price>3990</price>
<ISBN>4822229718</ISBN>
</order>
これは、JavaScriptのオブジェクト記法で記述すると以下のようになります。
var order = { name : "Webアプリケーションのセキュリティ完全対策", author : "徳丸浩他", price : 3990, ISBN : "4822229718" }
こっちの方が分かりやすいでよね。これでいいじゃん。
このように、JavaScriptのスクリプト内にオブジェクト・リテラルを記述するのであれば、JavaScriptに元々用意されている記法(これがJSONですが)で十分で、XMLを持ち出す必要はないと思います。
では、どういう場合にXML記法を使いたいかというと、Ajaxがすぐに思いつくわけですが、Ajaxで使うだけであればライブラリを用意しておけば済む話で、わざわざ言語のコアに組み込む必要はない。ということで、E4Xが本当に役に立つのは、JSONPでJSONのデータを読み込むように、<SCRIPT>で直接XMLを読むことではないかと思います。
連想配列とプロパティの関係
E4Xが理解できたとして、大垣さんの提示されたスクリプトを単純化すると以下のようになります。
123["eval"]("alert(1)");
この中の「123["eval"]」という部分は、数値123をオブジェクトとして使った連想配列になります。JavaScriptの場合、連想配列とオブジェクトのプロパティは等価ですから、上記以下のように書き直すことが出来ます(オブジェクト指向プログラム言語としてのJavaScript参照)。
123.eval("alert(1)");
これはすなわち、数値に対するevalメソッドを呼び出していることになります。数値にevalメソッドなんかあったっけ?
Object.eval メソッド
eval関数というものがあります。eval関数は文字列を引数としてとり、その文字列をJavaScriptとして実行するものです。
eval("alert('Hello')"); // Helloというダイアログが表示される
これに似たものに Object.eval メソッドがあります。ECMAScriptでは採用されていませんが、後方互換性のために残されています。Object.evalメソッドは、eval関数と似ていますが、スコープが異なります。
var a = 1; var obj = new Object; obj.a = 2; obj.eval("alert(a)"); // obj.a すなわち 2 が表示される eval("alert(a)"); // a すなわち 1 が表示される
上記の違いはともかく、「123.eval("alert(1)")」は、Objectクラスのevalが呼ばれ、「alert(1)」が実行されます。
大垣さんは何が言いたかったのか
大垣さんはのプログには以下のような記述がありますが・・
好むと好まざる関係なくFirefox 1.5から使えるのでWeb開発者は知っておかなればならないです。
今まで説明した中でWeb開発者が知っておくべきだと思うのは、連想配列とプロパティの関係くらいで、それ以外は、Firefoxでのみ使える機能(E4X)であったり、後方互換性のためにのみ残されている機能(Object.eval)なので、知っておかなくていいじゃんと思ってしまうのですね。
XSSとの関連でいえば、「'」や「"」を使わないXSSを技術できることは攻撃者にとって魅力的ですが、「'」や「"」はエスケープされるが、「<」がエスケープされていないという状況は考えにくいのです。大垣さんの書かれているのは、攻撃というよりは難読化ですね。
むしろ、奥一穂さんがKazuho@Cybozu Labs: E4X-XSS 脆弱性についてで書かれているように、<SCRIPT>で読み込まれるパターンの方が現実的な危険性を感じます。
いずれにせよ、E4Xのもたらすリスクについてはまだ議論が始まったばかりであり、Web開発者が知らなければならないのは、その議論の成果が出た後の話だと私は思います。