Browse Source

fix: block custom window.open when nativeWindowOpen is true (#23188) (#23224)

* fix: block custom window.open when nativeWindowOpen is true (#23188)

* fix lint

* Update chromium-spec.ts
Jeremy Apthorp 5 years ago
parent
commit
7dfcb5ef04
2 changed files with 38 additions and 0 deletions
  1. 8 0
      lib/browser/guest-window-manager.js
  2. 30 0
      spec-main/chromium-spec.ts

+ 8 - 0
lib/browser/guest-window-manager.js

@@ -188,6 +188,14 @@ const canAccessWindow = function (sender, target) {
 
 // Routed window.open messages with raw options
 ipcMainInternal.on('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', (event, url, frameName, features) => {
+  // This should only be allowed for senders that have nativeWindowOpen: false
+  {
+    const webPreferences = event.sender.getLastWebPreferences();
+    if (webPreferences.nativeWindowOpen || webPreferences.sandbox) {
+      event.returnValue = null;
+      throw new Error('GUEST_WINDOW_MANAGER_WINDOW_OPEN denied: expected native window.open');
+    }
+  }
   if (url == null || url === '') url = 'about:blank';
   if (frameName == null) frameName = '';
   if (features == null) features = '';

+ 30 - 0
spec-main/chromium-spec.ts

@@ -72,6 +72,36 @@ describe('reporting api', () => {
       server.close()
     }
   })
+
+  describe('window.open', () => {
+    it('denies custom open when nativeWindowOpen: true', async () => {
+      const w = new BrowserWindow({
+        show: false,
+        webPreferences: {
+          contextIsolation: false,
+          nodeIntegration: true,
+          nativeWindowOpen: true
+        }
+      });
+      w.loadURL('about:blank');
+
+      const previousListeners = process.listeners('uncaughtException');
+      process.removeAllListeners('uncaughtException');
+      try {
+        const uncaughtException = new Promise<Error>(resolve => {
+          process.once('uncaughtException', resolve);
+        });
+        expect(await w.webContents.executeJavaScript(`(${function () {
+          const ipc = process.electronBinding('ipc').ipc;
+          return ipc.sendSync(true, 'ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', ['', '', ''])[0];
+        }})()`)).to.be.null('null');
+        const exception = await uncaughtException;
+        expect(exception.message).to.match(/denied: expected native window\.open/);
+      } finally {
+        previousListeners.forEach(l => process.on('uncaughtException', l));
+      }
+    });
+  });
 })
 
 describe('window.postMessage', () => {