cross origin js security

nsScriptSecurityManagerを見ていたらjsのオブジェクトへのアクセスはget, set, call の3種類に分けて制御がかけられていて、それぞれSecurityLevelという構造体で設定しているのがわかった。

~/mozilla/caps/include/nsScriptSecurityManager.h

////////////////////
// Policy Storage //
////////////////////

// Property Policy
union SecurityLevel
{
    PRInt32  level;
    char*    capability;
};

// Security levels
// These values all have the low bit set (except UNDEFINED_ACCESS)
// to distinguish them from pointer values, because no pointer
// to allocated memory ever has the low bit set. A SecurityLevel
// contains either one of these constants or a pointer to a string
// representing the name of a capability.

#define SCRIPT_SECURITY_UNDEFINED_ACCESS 0
#define SCRIPT_SECURITY_ACCESS_IS_SET_BIT 1
#define SCRIPT_SECURITY_NO_ACCESS \
  ((1 << 0) | SCRIPT_SECURITY_ACCESS_IS_SET_BIT)
#define SCRIPT_SECURITY_SAME_ORIGIN_ACCESS \
  ((1 << 1) | SCRIPT_SECURITY_ACCESS_IS_SET_BIT)
#define SCRIPT_SECURITY_ALL_ACCESS \
  ((1 << 2) | SCRIPT_SECURITY_ACCESS_IS_SET_BIT)

#define SECURITY_ACCESS_LEVEL_FLAG(_sl) \
           ((_sl.level == 0) || \
            (_sl.level & SCRIPT_SECURITY_ACCESS_IS_SET_BIT))

けっきょくこれのどれが設定されているかに依存するが SCRIPT_SECURITY_SAME_ORIGIN_ACCESS という概念があるのを知れたのはちょっとした収穫だ。

追記

やっぱそんなに単純じゃない。
これはSCRAPBLOG : nsIScriptSecurityManager で危険なURIを除外するとのつながり。

Components.classesの場合

nsScriptSecurityManager::CheckPropertyAccessImplのチェックにひっかかってウインドウからはアクセスできない。securityLevel.levelはSCRIPT_SECURITY_SAME_ORIGIN_ACCESSになってる。

ちらっと見かけただけだけどnative/jsのラッパーを通すときはセキュリティチェックが入ってた。 XPCWrappedNative::CallMethodのところ。何をどういう基準でチェックしてるのか判ってないので意味ないけど。
ただこれでは unsafeWindow.* にGMからアクセスできない理由にならない。どっちもおなじoriginなはず。evalSandboxとcontentWindowでoriginが別になったとかなのかな。
あとfirebugの設定するwindow.consoleも説明できない。originはchromeのはずだけどcontentWindowからアクセスできる。

Mac 2 日目の僕でも出来た! XCode を使った Firefox デバッギング - IT戦記でビルドしたんだけど、デバッグ開始して一時停止したときに出てくるソースコードだとブレークポイント設定できるんだけど、ソースコード直接開いてブレークポイント設定しようとするとなぜか対応する行が見つからないって言われる。いわれるやつといわれないやつがある。どっちもコンパイルはされてる。リンクはされてないとかなのかな。よくわかんない。
2回ビルドしてみたけどだめでした。

nsScriptSecurityManager::CheckSameOriginPrincipalInternalで
NS_ERROR_DOM_PROP_ACCESS_DENIED
になってた。