Skip to content

Commit eb223f8

Browse files
juturuMarshallOfSound
authored andcommitted
Enable webview in sandbox renderer (electron#13435)
* Enable webview in sandbox renderer Security: Inherit embedder prefs onto webview * cache lastwebprefs
1 parent 42d173b commit eb223f8

4 files changed

Lines changed: 51 additions & 1 deletion

File tree

atom/renderer/atom_sandboxed_renderer_client.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ void InitializeBindings(v8::Local<v8::Object> binding,
9292
b.SetMethod("getHeapStatistics", &AtomBindings::GetHeapStatistics);
9393
b.SetMethod("getProcessMemoryInfo", &AtomBindings::GetProcessMemoryInfo);
9494
b.SetMethod("getSystemMemoryInfo", &AtomBindings::GetSystemMemoryInfo);
95+
96+
// Pass in CLI flags needed to setup the renderer
97+
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
98+
if (command_line->HasSwitch(switches::kGuestInstanceID))
99+
b.Set(options::kGuestInstanceID,
100+
command_line->GetSwitchValueASCII(switches::kGuestInstanceID));
95101
}
96102

97103
class AtomSandboxedRenderFrameObserver : public AtomRenderFrameObserver {

lib/browser/guest-view-manager.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,23 @@ const attachGuest = function (event, elementInstanceId, guestInstanceId, params)
240240
webPreferences.disablePopups = true
241241
}
242242

243+
// Security options that guest will always inherit from embedder
244+
const inheritedWebPreferences = new Map([
245+
['contextIsolation', true],
246+
['javascript', false],
247+
['nativeWindowOpen', true],
248+
['nodeIntegration', false],
249+
['sandbox', true]
250+
])
251+
252+
// Inherit certain option values from embedder
253+
const lastWebPreferences = embedder.getLastWebPreferences()
254+
for (const [name, value] of inheritedWebPreferences) {
255+
if (lastWebPreferences[name] === value) {
256+
webPreferences[name] = value
257+
}
258+
}
259+
243260
embedder.emit('will-attach-webview', event, webPreferences, params)
244261
if (event.defaultPrevented) {
245262
if (guest.viewInstanceId == null) guest.viewInstanceId = params.instanceId

lib/sandboxed_renderer/init.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@ if (window.location.protocol === 'chrome-devtools:') {
7878
require('../renderer/inspector')
7979
}
8080

81+
if (binding.guestInstanceId) {
82+
process.guestInstanceId = parseInt(binding.guestInstanceId)
83+
}
84+
85+
if (!process.guestInstanceId && preloadProcess.argv.indexOf('--webview-tag=true') !== -1) {
86+
// don't allow recursive `<webview>`
87+
require('../renderer/web-view/web-view')
88+
require('../renderer/web-view/web-view-attributes')
89+
}
90+
8191
// Wrap the script into a function executed in global scope. It won't have
8292
// access to the current scope, so we'll expose a few objects as arguments:
8393
//

spec/api-browser-window-spec.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const os = require('os')
88
const qs = require('querystring')
99
const http = require('http')
1010
const {closeWindow} = require('./window-helpers')
11-
11+
const {emittedOnce} = require('./events-helpers')
1212
const {ipcRenderer, remote, screen} = require('electron')
1313
const {app, ipcMain, BrowserWindow, BrowserView, protocol, session, webContents} = remote
1414

@@ -1573,6 +1573,23 @@ describe('BrowserWindow module', () => {
15731573
})
15741574
w.loadURL('file://' + path.join(fixtures, 'api', 'preload.html'))
15751575
})
1576+
1577+
it('webview in sandbox renderer', async () => {
1578+
w.destroy()
1579+
w = new BrowserWindow({
1580+
show: false,
1581+
webPreferences: {
1582+
sandbox: true,
1583+
preload: preload,
1584+
webviewTag: true
1585+
}
1586+
})
1587+
w.loadURL(`file://${fixtures}/pages/webview-did-attach-event.html`)
1588+
1589+
const [, webContents] = await emittedOnce(w.webContents, 'did-attach-webview')
1590+
const [, id] = await emittedOnce(ipcMain, 'webview-dom-ready')
1591+
expect(webContents.id).to.equal(id)
1592+
})
15761593
})
15771594

15781595
describe('nativeWindowOpen option', () => {

0 commit comments

Comments
 (0)