From 97fb15ac49202ab110138bbac643e548b752c8fd Mon Sep 17 00:00:00 2001 From: Jeremy Apthorp Date: Wed, 11 Apr 2018 18:57:40 -0700 Subject: [PATCH] Enable WebFrame method forwarding in sandboxed renderers (#12538) * Enable WebFrame method forwarding in sandboxed renderers Fixes #9073 * Non-change to kick CI --- filenames.gypi | 1 + lib/renderer/init.js | 37 +-------------------------------- lib/renderer/web-frame-init.js | 38 ++++++++++++++++++++++++++++++++++ lib/sandboxed_renderer/init.js | 2 ++ spec/api-web-contents-spec.js | 21 ++++++++++++++++++- vendor/libchromiumcontent | 2 +- 6 files changed, 63 insertions(+), 38 deletions(-) create mode 100644 lib/renderer/web-frame-init.js diff --git a/filenames.gypi b/filenames.gypi index ebaeb395f3e9..05fb89b2129d 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -64,6 +64,7 @@ 'lib/renderer/inspector.js', 'lib/renderer/override.js', 'lib/renderer/security-warnings.js', + 'lib/renderer/web-frame-init.js', 'lib/renderer/window-setup.js', 'lib/renderer/web-view/guest-view-internal.js', 'lib/renderer/web-view/web-view.js', diff --git a/lib/renderer/init.js b/lib/renderer/init.js index 795de0627403..93129849ae04 100644 --- a/lib/renderer/init.js +++ b/lib/renderer/init.js @@ -3,7 +3,6 @@ const events = require('events') const path = require('path') const Module = require('module') -const resolvePromise = Promise.resolve.bind(Promise) // We modified the original process.argv to let node.js load the // init.js, we need to restore it here. @@ -26,7 +25,6 @@ var v8Util = process.atomBinding('v8_util') v8Util.setHiddenValue(global, 'ipc', new events.EventEmitter()) // Use electron module after everything is ready. -const electron = require('electron') const { warnAboutNodeWithRemoteContent, @@ -40,40 +38,7 @@ const { shouldLogSecurityWarnings } = require('./security-warnings') -// Call webFrame method. -electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', (event, method, args) => { - electron.webFrame[method](...args) -}) - -electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_SYNC_WEB_FRAME_METHOD', (event, requestId, method, args) => { - const result = electron.webFrame[method](...args) - event.sender.send(`ELECTRON_INTERNAL_BROWSER_SYNC_WEB_FRAME_RESPONSE_${requestId}`, result) -}) - -electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', (event, requestId, method, args) => { - const responseCallback = function (result) { - resolvePromise(result) - .then((resolvedResult) => { - event.sender.send(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, null, resolvedResult) - }) - .catch((resolvedError) => { - if (resolvedError instanceof Error) { - // Errors get lost, because: JSON.stringify(new Error('Message')) === {} - // Take the serializable properties and construct a generic object - resolvedError = { - message: resolvedError.message, - stack: resolvedError.stack, - name: resolvedError.name, - __ELECTRON_SERIALIZED_ERROR__: true - } - } - - event.sender.send(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, resolvedError) - }) - } - args.push(responseCallback) - electron.webFrame[method](...args) -}) +require('./web-frame-init')() // Process command line arguments. let nodeIntegration = 'false' diff --git a/lib/renderer/web-frame-init.js b/lib/renderer/web-frame-init.js new file mode 100644 index 000000000000..deabcc42a013 --- /dev/null +++ b/lib/renderer/web-frame-init.js @@ -0,0 +1,38 @@ +const electron = require('electron') + +module.exports = () => { + // Call webFrame method + electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', (event, method, args) => { + electron.webFrame[method](...args) + }) + + electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_SYNC_WEB_FRAME_METHOD', (event, requestId, method, args) => { + const result = electron.webFrame[method](...args) + event.sender.send(`ELECTRON_INTERNAL_BROWSER_SYNC_WEB_FRAME_RESPONSE_${requestId}`, result) + }) + + electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', (event, requestId, method, args) => { + const responseCallback = function (result) { + Promise.resolve(result) + .then((resolvedResult) => { + event.sender.send(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, null, resolvedResult) + }) + .catch((resolvedError) => { + if (resolvedError instanceof Error) { + // Errors get lost, because: JSON.stringify(new Error('Message')) === {} + // Take the serializable properties and construct a generic object + resolvedError = { + message: resolvedError.message, + stack: resolvedError.stack, + name: resolvedError.name, + __ELECTRON_SERIALIZED_ERROR__: true + } + } + + event.sender.send(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, resolvedError) + }) + } + args.push(responseCallback) + electron.webFrame[method](...args) + }) +} diff --git a/lib/sandboxed_renderer/init.js b/lib/sandboxed_renderer/init.js index e8883ba61d04..6644a9709c24 100644 --- a/lib/sandboxed_renderer/init.js +++ b/lib/sandboxed_renderer/init.js @@ -32,6 +32,8 @@ const preloadModules = new Map([ ['timers', require('timers')] ]) +require('../renderer/web-frame-init')() + // Pass different process object to the preload script(which should not have // access to things like `process.atomBinding`). const preloadProcess = new events.EventEmitter() diff --git a/spec/api-web-contents-spec.js b/spec/api-web-contents-spec.js index 51692778d853..dd31343edbe7 100644 --- a/spec/api-web-contents-spec.js +++ b/spec/api-web-contents-spec.js @@ -92,7 +92,7 @@ describe('webContents module', () => { }) }) - describe('setDevToolsWebCotnents() API', () => { + describe('setDevToolsWebContents() API', () => { it('sets arbitry webContents as devtools', (done) => { let devtools = new BrowserWindow({show: false}) devtools.webContents.once('dom-ready', () => { @@ -754,4 +754,23 @@ describe('webContents module', () => { }) }) }) + + describe('webframe messages in sandboxed contents', () => { + it('responds to executeJavaScript', (done) => { + w.destroy() + w = new BrowserWindow({ + show: false, + webPreferences: { + sandbox: true + } + }) + w.webContents.once('did-finish-load', () => { + w.webContents.executeJavaScript('37 + 5', (result) => { + assert.equal(result, 42) + done() + }) + }) + w.loadURL('about:blank') + }) + }) }) diff --git a/vendor/libchromiumcontent b/vendor/libchromiumcontent index f1fc5cfb3d17..90df5e9e8881 160000 --- a/vendor/libchromiumcontent +++ b/vendor/libchromiumcontent @@ -1 +1 @@ -Subproject commit f1fc5cfb3d17d73687574b6ee4636dd1a9dbb7b5 +Subproject commit 90df5e9e88810a49a2e0db71f4e8d3a635108efa