diff --git a/additions/juggler/content/FrameTree.js b/additions/juggler/content/FrameTree.js index 65672be..c67beb4 100644 --- a/additions/juggler/content/FrameTree.js +++ b/additions/juggler/content/FrameTree.js @@ -411,7 +411,11 @@ class Frame { this._parentFrame = parentFrame; parentFrame._children.add(this); } + + this.allowMW = ChromeUtils.camouGetBool('allowMainWorld', false); + this.forceScopeAccess = ChromeUtils.camouGetBool('forceScopeAccess', false); + this.masterSandbox = undefined; this._lastCommittedNavigationId = null; this._pendingNavigationId = null; @@ -505,21 +509,44 @@ class Frame { }; } - _createIsolatedContext(name) { - const principal = [this.domWindow()]; // extended principal - const sandbox = Cu.Sandbox(principal, { - sandboxPrototype: this.domWindow(), - wantComponents: false, - wantExportHelpers: false, - wantXrays: true, - }); + // Camoufox: Add a "God mode" master sandbox with it's own compartment + getMasterSandbox() { + if (!this.masterSandbox) { + this.masterSandbox = Cu.Sandbox( + Services.scriptSecurityManager.getSystemPrincipal(), + { + sandboxPrototype: this.domWindow(), + wantComponents: false, + wantExportHelpers: false, + wantXrays: true, + freshCompartment: true, + } + ); + } + return this.masterSandbox; + } + + _createIsolatedContext(name, useMaster=false) { + let sandbox; + // Camoufox: Use the master sandbox (with system principle scope access) + if (useMaster && this.forceScopeAccess) { + sandbox = this.getMasterSandbox(); + } else { + // Standard access (run in domWindow principal) + sandbox = Cu.Sandbox([this.domWindow()], { + sandboxPrototype: this.domWindow(), + wantComponents: false, + wantExportHelpers: false, + wantXrays: true, + }); + } const world = this._runtime.createExecutionContext(this.domWindow(), sandbox, { frameId: this.id(), name, }); // Camoufox: Create a main world for the isolated context - if (ChromeUtils.camouGetBool('allowMainWorld', false)) { - const mainWorld = this._runtime.createMW(this.domWindow(), this.domWindow()); + if (this.allowMW) { + const mainWorld = this._runtime.createMW(this.domWindow(), sandbox); world.mainEquivalent = mainWorld; } this._worldNameToContext.set(name, world); @@ -559,7 +586,7 @@ class Frame { this._runtime.destroyExecutionContext(context); this._worldNameToContext.clear(); // Camoufox: Scope the initial execution context to prevent leaks - this._createIsolatedContext(''); + this._createIsolatedContext('', true); for (const [name, world] of this._frameTree._isolatedWorlds) { if (name) this._createIsolatedContext(name); diff --git a/patches/shadow-root-bypass.patch b/patches/shadow-root-bypass.patch new file mode 100644 index 0000000..b8a9ac1 --- /dev/null +++ b/patches/shadow-root-bypass.patch @@ -0,0 +1,14 @@ +diff --git a/dom/webidl/Element.webidl b/dom/webidl/Element.webidl +index 7163fac826..c0c201e29d 100644 +--- a/dom/webidl/Element.webidl ++++ b/dom/webidl/Element.webidl +@@ -288,6 +288,9 @@ partial interface Element { + [BinaryName="shadowRootByMode"] + readonly attribute ShadowRoot? shadowRoot; + ++ [Func="Document::IsCallerChromeOrAddon", BinaryName="shadowRoot"] ++ readonly attribute ShadowRoot? shadowRootUnl; ++ + [Func="Document::IsCallerChromeOrAddon", BinaryName="shadowRoot"] + readonly attribute ShadowRoot? openOrClosedShadowRoot; + diff --git a/settings/camoucfg.jvv b/settings/camoucfg.jvv index 4ac015f..f87844f 100644 --- a/settings/camoucfg.jvv +++ b/settings/camoucfg.jvv @@ -292,6 +292,7 @@ "showcursor": "bool", "allowMainWorld": "bool", + "forceScopeAccess": "bool", "memorysaver": "bool", "addons": "array[str]", "debug": "bool" diff --git a/settings/properties.json b/settings/properties.json index 22262ed..f8bd8a2 100644 --- a/settings/properties.json +++ b/settings/properties.json @@ -94,6 +94,7 @@ { "property": "mediaDevices:speakers", "type": "uint" }, { "property": "mediaDevices:enabled", "type": "bool" }, { "property": "allowMainWorld", "type": "bool" }, + { "property": "forceScopeAccess", "type": "bool" }, { "property": "memorysaver", "type": "bool" }, { "property": "addons", "type": "array" }, { "property": "debug", "type": "bool" }