------------------------------------------------
2015年12月のMicrosoftの月例アップデートで修正された、Internet ExplorerとEdgeのXSSフィルターに存在した問題(CVE-2015-6144 および CVE-2015-6176)について書きます。
2015 年 12 月のマイクロソフト セキュリティ情報の概要
https://technet.microsoft.com/ja-jp/library/security/ms15-dec.aspx
修正された問題は、2015年10月に行われたセキュリティカンファレンスのCODE BLUEで詳細を伏せて発表した、IE/EdgeのXSSフィルターの動作を利用してXSS攻撃する手法の一部です。「一部」と書いたように、今回のパッチでは、報告した問題の全てが修正された訳ではありませんでした。当初、発表するつもりで作った、攻撃手法の詳細も含めたスライドを、未修正の部分を伏せて以下で公開します。
また、以下で3つの手法のPoCを公開しています。修正され次第、他のPoCも公開します。
http://l0.cm/xxn/
詳しい原理等については資料を見てもらうとして、この記事では、ざっくりと手法に触れながら、今回施された修正方法に言及したいと思います。
1. style属性の遮断を悪用するパターン
次のような、style属性の追加によるXSSの遮断を、
</style>
の閉じタグに誤マッチさせることで、閉じタグを破壊し、攻撃を成立させます。Microsoftはこの問題に対し、style属性部の遮断時だけ、強制的に
mode=block
の動作にすることで回避したようです。確かに問題は起きなくなりますが、これじゃあ、X-XSS-Protection:1
の動作とはなんだったのか…、という気がします。ただ、確実な回避策にはなっているので、ひとまずはこれでよいと思います。(実際、僕はデフォルト動作をひとまず
mode=block
にすることで回避したらどうかとMSに提案していました。)2. 文字列リテラルの遮断を悪用するパターン その1( <script src=***></script> を利用)
次のような、文字列リテラルでの、プロパティアクセス後の代入による攻撃(実際には例えば、
";document.body.innerHTML="攻撃文字列"//
のような形で攻撃します)の遮断を利用し、スクリプトタグの
src
の値に誤マッチさせることで、外部リソースをスクリプトとしてロードして攻撃します。どう修正されたかは、次の手法でまとめて紹介します。
3. 文字列リテラルの遮断を悪用するパターン その2( <link rel=stylesheet href=***> を利用)
同じく、文字列リテラルでの遮断を、無関係の文字列に誤マッチさせます。
今度は、
<link>
タグのhref
の相対パスの.
を利用し、攻撃に繋げるという方法です。2と3の問題のMicrosoftの修正にはびっくりしました。
プロパティアクセス後の代入の遮断時だけ、
.
を、これまでの#
の代わりに、^
(0x5E)に置換するよう変更したのです!なんじゃそりゃ~(^_^)!確かに、この2つの問題は回避できるかもしれませんが、この修正は良いとは思えません。
JavaScriptにおいて、
^
は演算子です。document.location
がdocument^location
に変わってもエラーになりません。この時点で、 既存のインラインスクリプトに含まれる.
をうまいこと^
に変えることで、エラーを起こさずに何かおかしな動作を意図的に起こせるかもしれないことは容易に想像できます。じゃあ、.
が JavaScriptの正規表現に含まれていたら、そしてそれが^
に置換されたら、どうなるでしょう…?考え出すと、これならOKという気はまったくしません。このような修正を繰り返しても、XSSフィルターを使ったXSSパズルのピースが変わっただけであり、本質的には何も安全になっていないと思います。
報告では、XSSフィルターの遮断方法はこのままじゃまずいよね、という思いも伝えられたと思っていただけに、今回のパッチの回避方法は、現在の遮断方法に危機感を持っていないとしか思えないものであり、非常に残念でした。
もう一度コンタクトし直して、そういった思いを伝え、今回、紹介を伏せた、まだ修正されていないXSSフィルターの問題が修正される時には、根本的な部分まで改善されることを期待したいと思います。
開発者の方には、資料の中でも書いた通り、引き続き、自分のサイトのすべてのページで、
X-XSS-Protection:1;mode=block
かX-XSS-Protection:0
のヘッダを指定することを推奨したいと思います。これがXSSフィルターによって、不本意にページを変更されることの開発者側でできる回避策になります。