Browse Source

Merge pull request #13539 from trop-bot/3-0-x-bp-enable-webview-in-sandbox-renderer-1530547750986

Backport (3-0-x) - Enable webview in sandbox renderer
John Kleinschmidt 6 years ago
parent
commit
8f8d198c5a

+ 6 - 0
atom/renderer/atom_sandboxed_renderer_client.cc

@@ -92,6 +92,12 @@ void InitializeBindings(v8::Local<v8::Object> binding,
   b.SetMethod("getHeapStatistics", &AtomBindings::GetHeapStatistics);
   b.SetMethod("getProcessMemoryInfo", &AtomBindings::GetProcessMemoryInfo);
   b.SetMethod("getSystemMemoryInfo", &AtomBindings::GetSystemMemoryInfo);
+
+  // Pass in CLI flags needed to setup the renderer
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(switches::kGuestInstanceID))
+    b.Set(options::kGuestInstanceID,
+        command_line->GetSwitchValueASCII(switches::kGuestInstanceID));
 }
 
 class AtomSandboxedRenderFrameObserver : public AtomRenderFrameObserver {

+ 17 - 0
lib/browser/guest-view-manager.js

@@ -240,6 +240,23 @@ const attachGuest = function (event, elementInstanceId, guestInstanceId, params)
     webPreferences.disablePopups = true
   }
 
+  // Security options that guest will always inherit from embedder
+  const inheritedWebPreferences = new Map([
+    ['contextIsolation', true],
+    ['javascript', false],
+    ['nativeWindowOpen', true],
+    ['nodeIntegration', false],
+    ['sandbox', true]
+  ])
+
+  // Inherit certain option values from embedder
+  const lastWebPreferences = embedder.getLastWebPreferences()
+  for (const [name, value] of inheritedWebPreferences) {
+    if (lastWebPreferences[name] === value) {
+      webPreferences[name] = value
+    }
+  }
+
   embedder.emit('will-attach-webview', event, webPreferences, params)
   if (event.defaultPrevented) {
     if (guest.viewInstanceId == null) guest.viewInstanceId = params.instanceId

+ 10 - 0
lib/sandboxed_renderer/init.js

@@ -78,6 +78,16 @@ if (window.location.protocol === 'chrome-devtools:') {
   require('../renderer/inspector')
 }
 
+if (binding.guestInstanceId) {
+  process.guestInstanceId = parseInt(binding.guestInstanceId)
+}
+
+if (!process.guestInstanceId && preloadProcess.argv.indexOf('--webview-tag=true') !== -1) {
+  // don't allow recursive `<webview>`
+  require('../renderer/web-view/web-view')
+  require('../renderer/web-view/web-view-attributes')
+}
+
 // Wrap the script into a function executed in global scope. It won't have
 // access to the current scope, so we'll expose a few objects as arguments:
 //

+ 18 - 1
spec/api-browser-window-spec.js

@@ -8,7 +8,7 @@ const os = require('os')
 const qs = require('querystring')
 const http = require('http')
 const {closeWindow} = require('./window-helpers')
-
+const {emittedOnce} = require('./events-helpers')
 const {ipcRenderer, remote, screen} = require('electron')
 const {app, ipcMain, BrowserWindow, BrowserView, protocol, session, webContents} = remote
 
@@ -1581,6 +1581,23 @@ describe('BrowserWindow module', () => {
         })
         w.loadURL('file://' + path.join(fixtures, 'api', 'preload.html'))
       })
+
+      it('webview in sandbox renderer', async () => {
+        w.destroy()
+        w = new BrowserWindow({
+          show: false,
+          webPreferences: {
+            sandbox: true,
+            preload: preload,
+            webviewTag: true
+          }
+        })
+        w.loadURL(`file://${fixtures}/pages/webview-did-attach-event.html`)
+
+        const [, webContents] = await emittedOnce(w.webContents, 'did-attach-webview')
+        const [, id] = await emittedOnce(ipcMain, 'webview-dom-ready')
+        expect(webContents.id).to.equal(id)
+      })
     })
 
     describe('nativeWindowOpen option', () => {