Skip to content

Commit

Permalink
Enable WebFrame method forwarding in sandboxed renderers (#12538)
Browse files Browse the repository at this point in the history
* Enable WebFrame method forwarding in sandboxed renderers

Fixes #9073

* Non-change to kick CI
  • Loading branch information
nornagon authored and MarshallOfSound committed Apr 12, 2018
1 parent 558d36c commit 97fb15a
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 38 deletions.
1 change: 1 addition & 0 deletions filenames.gypi
Expand Up @@ -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',
Expand Down
37 changes: 1 addition & 36 deletions lib/renderer/init.js
Expand Up @@ -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.
Expand All @@ -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,
Expand All @@ -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'
Expand Down
38 changes: 38 additions & 0 deletions 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)
})
}
2 changes: 2 additions & 0 deletions lib/sandboxed_renderer/init.js
Expand Up @@ -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()
Expand Down
21 changes: 20 additions & 1 deletion spec/api-web-contents-spec.js
Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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')
})
})
})
2 changes: 1 addition & 1 deletion vendor/libchromiumcontent
Submodule libchromiumcontent updated 0 files

0 comments on commit 97fb15a

Please sign in to comment.