principal実習#1

fx3だとGreasemonkeyからunsafeWindow.consoleにアクセスすると Security Manager vetoed action って出る。
これはべつにunsafeWindowのプロパティにアクセスできなくなったわけじゃなくてprincipalでjsのセキュリティが管理されていることによる結果。

unsafeWindow.consoleの場合

GMのuserscriptからunsafeWindow.consoleにアクセスするとき、objectになるunsafeWindow.consoleは、Firebugの中で設定される。

    watchWindow: function(context, win)
    {
        // XXXjoe Move this to Firebug.Console
        if (!win.console)
            win.console = new FirebugConsole(context, win);

unsafeWindow.consoleの__parent__をたどっていくとchromeのwindowになるのでunsafeWindow.consoleはsystem principalを持っている。

subjectのprincipalを決定するために、呼び出した関数をたどっていくとsandboxにいきつく。sandboxはウインドウのprincipalになっている。


ウインドウのprincipalのsubjectでsystem principalのobjectにアクセスしているのでセキュリティマネージャのチェックに引っかかる。それが Security Manager vetoed action としてfirebugのコンソールに表示される。

unsafeWindow.Hatenaの場合

はてなスターのあるページだとwindow.Hatenaが定義されてるのかな。おなじunsafeWindow経由でもunsafeWindow.HatenaならアクセスできるのをFirefox3 の Greasemonkey, unsafeWindow 内の prototype がとれない - 冬通りに消え行く制服ガールは、夢物語にリアルを求めない。 - subtechで知った(自分でconsole以外にアクセスしてみたことがまったくなかったのでした)。

window.Hatenaは、ページ内のjavascriptで設定される。ページ内のjavascriptが持つprincipalはそのページのprincipalだ。したがってwindow.Hatenaはページのprincipalを持つ。
GreasemonkeyのuserscriptからみたunsafeWindow.Hatenaは、ページの中のwindow.Hatenaと同じものなのでおなじprincipalになる。だからobjectのprincipalはページのprincipalになる。

unsafeWindow.consoleの場合と同様、userscriptからアクセスするときsubjectのprincipalはページのprincipalになる。


subjectとobjectのprincipalが一致しているので今度はエラーにならない。

設計上のジレンマ

firefoxの設計上、Greasemonkey実行時のprincipalをページのwindowとおなじprincipalにしないとunsafeWindowのプロパティが変更できない。でも同じにすることで逆にunsafeWindowで書いた関数からもGreasemonkey側の関数にアクセスできるようになる。拡張機能のようにsystem principalを持っていればprincipalが異なるものにもふつうにアクセスできるんだけどgreasemonkeyはuserscriptにはXPCOMを触らせないというデザインなのでこうなっちゃう。
system principalとふつうのprincipalのあいだにもう一段階用意して、下から上はNGだけど上から下はokっていう仕組みを入れたらGMの問題はきれいに解決できるけど影響範囲がすんごいでかそうだと思いました。

prototypeとれないのはsandbox内のコードになにか制約があるのかなー。