diff --git a/src/extension-support/tw-unsandboxed-extension-runner.js b/src/extension-support/tw-unsandboxed-extension-runner.js index 08da34a3..fa86bb72 100644 --- a/src/extension-support/tw-unsandboxed-extension-runner.js +++ b/src/extension-support/tw-unsandboxed-extension-runner.js @@ -97,6 +97,9 @@ const setupUnsandboxedExtensionAPI = vm => new Promise(resolve => { if (!await Scratch.canOpenWindow(url)) { throw new Error(`Permission to open tab ${url} rejected.`); } + // Use noreferrer to prevent new tab from accessing `window.opener` + const baseFeatures = 'noreferrer'; + features = features ? `${baseFeatures},${features}` : baseFeatures; return window.open(url, '_blank', features); }; diff --git a/test/unit/tw_unsandboxed_extensions.js b/test/unit/tw_unsandboxed_extensions.js index 3cfcd0fe..abc0091d 100644 --- a/test/unit/tw_unsandboxed_extensions.js +++ b/test/unit/tw_unsandboxed_extensions.js @@ -218,8 +218,8 @@ test('openWindow', async t => { UnsandboxedExtensionRunner.setupUnsandboxedExtensionAPI(vm); global.Scratch.canOpenWindow = url => url === 'https://example.com/2'; await t.rejects(global.Scratch.openWindow('https://example.com/1'), /Permission to open tab https:\/\/example.com\/1 rejected/); - t.equal(await global.Scratch.openWindow('https://example.com/2'), '[Window https://example.com/2 target=_blank features=]'); - t.equal(await global.Scratch.openWindow('https://example.com/2', 'popup=1'), '[Window https://example.com/2 target=_blank features=popup=1]'); + t.equal(await global.Scratch.openWindow('https://example.com/2'), '[Window https://example.com/2 target=_blank features=noreferrer]'); + t.equal(await global.Scratch.openWindow('https://example.com/2', 'popup=1'), '[Window https://example.com/2 target=_blank features=noreferrer,popup=1]'); t.end(); });