Add option to override webview security

This commit is contained in:
Hari Krishna Reddy Juturu 2017-05-06 22:10:42 -07:00
parent b4a8ed01f1
commit 94d054cf11
7 changed files with 64 additions and 2 deletions

View file

@ -101,6 +101,13 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
if (web_preferences.GetBoolean(options::kNodeIntegrationInWorker, &b) && b)
command_line->AppendSwitch(switches::kNodeIntegrationInWorker);
// Check if webview tag creation is overriden.
bool enable_webview_override = false;
web_preferences.GetBoolean(options::kEnableWebViewOverride,
&enable_webview_override);
command_line->AppendSwitchASCII(switches::kEnableWebViewOverride,
enable_webview_override ? "true" : "false");
// If the `sandbox` option was passed to the BrowserWindow's webPreferences,
// pass `--enable-sandbox` to the renderer so it won't have any node.js
// integration.

View file

@ -128,6 +128,9 @@ const char kDisableBlinkFeatures[] = "disableBlinkFeatures";
// Enable the node integration in WebWorker.
const char kNodeIntegrationInWorker[] = "nodeIntegrationInWorker";
// Enable the web view tag irrespective of node-integration setting.
const char kEnableWebViewOverride[] = "enableWebViewOverride";
} // namespace options
namespace switches {
@ -172,6 +175,7 @@ const char kGuestInstanceID[] = "guest-instance-id";
const char kOpenerID[] = "opener-id";
const char kScrollBounce[] = "scroll-bounce";
const char kHiddenPage[] = "hidden-page";
const char kEnableWebViewOverride[] = "enable-webview-override";
// Command switch passed to renderer process to control nodeIntegration.
const char kNodeIntegrationInWorker[] = "node-integration-in-worker";

View file

@ -64,6 +64,7 @@ extern const char kScrollBounce[];
extern const char kBlinkFeatures[];
extern const char kDisableBlinkFeatures[];
extern const char kNodeIntegrationInWorker[];
extern const char kEnableWebViewOverride[];
} // namespace options
@ -93,6 +94,7 @@ extern const char kOpenerID[];
extern const char kScrollBounce[];
extern const char kHiddenPage[];
extern const char kNodeIntegrationInWorker[];
extern const char kEnableWebViewOverride[];
extern const char kWidevineCdmPath[];
extern const char kWidevineCdmVersion[];

View file

@ -307,6 +307,11 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
'Electron Isolated Context' entry in the combo box at the top of the
Console tab. **Note:** This option is currently experimental and may
change or be removed in future Electron releases.
* `enableWebViewOverride` Boolean (optional) - Whether to enable [webview-tag](webview-tag.md)
ignoring the security restriction based on `nodeIntegration`. Enabling this option will
have security implication on creating `webview` with `nodeIntegration` disabled. To avoid the
security risk, listen to `will-create-webview` event on [web-contents](web-contents.md) and
stop creating `webview` or removing preload scripts.
When setting minimum or maximum window size with `minWidth`/`maxWidth`/
`minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from

View file

@ -15,6 +15,10 @@ between your app and embedded content will be asynchronous. This keeps your app
safe from the embedded content. **Note:** Most methods called on the
webview from the host page require a syncronous call to the main process.
For security purposes, `webview` can only be used in `BrowserWindow`s that have
`nodeIntegration` enabled. You can override this security restiction using
`enableWebViewOverride` option on [browser-window](browser-window.md).
## Example
To embed a web page in your app, add the `webview` tag to your app's embedder

View file

@ -57,6 +57,7 @@ let nodeIntegration = 'false'
let preloadScript = null
let isBackgroundPage = false
let appPath = null
let enableWebView = false
for (let arg of process.argv) {
if (arg.indexOf('--guest-instance-id=') === 0) {
// This is a guest web view.
@ -72,6 +73,8 @@ for (let arg of process.argv) {
isBackgroundPage = true
} else if (arg.indexOf('--app-path=') === 0) {
appPath = arg.substr(arg.indexOf('=') + 1)
} else if (arg.indexOf('--enable-webview-override=') === 0) {
enableWebView = arg.substr(arg.indexOf('=') + 1)
}
}
@ -94,7 +97,7 @@ if (window.location.protocol === 'chrome-devtools:') {
require('./content-scripts-injector')
// Load webview tag implementation.
if (process.guestInstanceId == null) {
if ((nodeIntegration === 'true' || enableWebView === 'true') && process.guestInstanceId == null) {
require('./web-view/web-view')
require('./web-view/web-view-attributes')
}

View file

@ -8,7 +8,7 @@ const {closeWindow} = require('./window-helpers')
const isCI = remote.getGlobal('isCi')
describe('<webview> tag', function () {
describe.only('<webview> tag', function () {
this.timeout(3 * 60 * 1000)
var fixtures = path.join(__dirname, 'fixtures')
@ -36,6 +36,43 @@ describe('<webview> tag', function () {
w.loadURL('file://' + fixtures + '/pages/webview-no-script.html')
})
it('is disabled when nodeIntegration is disabled', function (done) {
w = new BrowserWindow({
show: false,
webPreferences: {
nodeIntegration: false,
preload: path.join(fixtures, 'module', 'preload-webview.js')
}
})
ipcMain.once('webview', function (event, type) {
if (type === 'undefined') {
done()
} else {
done('WebView still exists')
}
})
w.loadURL('file://' + fixtures + '/pages/webview-no-script.html')
})
it('is enabled when override is set', function (done) {
w = new BrowserWindow({
show: false,
webPreferences: {
nodeIntegration: false,
preload: path.join(fixtures, 'module', 'preload-webview.js'),
enableWebViewOverride: true
}
})
ipcMain.once('webview', function (event, type) {
if (type !== 'undefined') {
done()
} else {
done('WebView is not created')
}
})
w.loadURL('file://' + fixtures + '/pages/webview-no-script.html')
})
describe('src attribute', function () {
it('specifies the page to load', function (done) {
webview.addEventListener('console-message', function (e) {