Skip to content

Commit c798a6e

Browse files
authored
fix: block custom window.open when nativeWindowOpen is true (electron#23188)
1 parent 3ac4fa8 commit c798a6e

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

lib/browser/guest-window-manager.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,12 @@ const canAccessWindow = function (sender, target) {
219219

220220
// Routed window.open messages with raw options
221221
ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, url, frameName, features) => {
222+
// This should only be allowed for senders that have nativeWindowOpen: false
223+
const webPreferences = event.sender.getLastWebPreferences();
224+
if (webPreferences.nativeWindowOpen || webPreferences.sandbox) {
225+
event.returnValue = null;
226+
throw new Error('GUEST_WINDOW_MANAGER_WINDOW_OPEN denied: expected native window.open');
227+
}
222228
if (url == null || url === '') url = 'about:blank';
223229
if (frameName == null) frameName = '';
224230
if (features == null) features = '';

spec-main/chromium-spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,34 @@ describe('chromium features', () => {
654654
const [, window] = await emittedOnce(app, 'browser-window-created');
655655
expect(window.getTitle()).to.equal('__proto__');
656656
});
657+
658+
it('denies custom open when nativeWindowOpen: true', async () => {
659+
const w = new BrowserWindow({
660+
show: false,
661+
webPreferences: {
662+
contextIsolation: false,
663+
nodeIntegration: true,
664+
nativeWindowOpen: true
665+
}
666+
});
667+
w.loadURL('about:blank');
668+
669+
const previousListeners = process.listeners('uncaughtException');
670+
process.removeAllListeners('uncaughtException');
671+
try {
672+
const uncaughtException = new Promise<Error>(resolve => {
673+
process.once('uncaughtException', resolve);
674+
});
675+
expect(await w.webContents.executeJavaScript(`(${function () {
676+
const ipc = process.electronBinding('ipc').ipc;
677+
return ipc.sendSync(true, 'ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', ['', '', ''])[0];
678+
}})()`)).to.be.null();
679+
const exception = await uncaughtException;
680+
expect(exception.message).to.match(/denied: expected native window\.open/);
681+
} finally {
682+
previousListeners.forEach(l => process.on('uncaughtException', l));
683+
}
684+
});
657685
});
658686

659687
describe('window.opener', () => {

0 commit comments

Comments
 (0)