8000 Set appropriate defaults for webview options by ckerr · Pull Request #12271 · electron/electron · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Set appropriate defaults for webview options #12271

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions atom/browser/api/atom_api_web_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1825,6 +1825,14 @@ v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) {
return mate::ConvertToV8(isolate, *web_preferences->web_preferences());
}

v8::Local<v8::Value> WebContents::GetLastWebPreferences(v8::Isolate* isolate) {
WebContentsPreferences* web_preferences =
WebContentsPreferences::FromWebContents(web_contents());
if (!web_preferences)
return v8::Null(isolate);
return mate::ConvertToV8(isolate, *web_preferences->last_web_preferences());
}

v8::Local<v8::Value> WebContents::GetOwnerBrowserWindow() {
if (owner_window())
return BrowserWindow::From(isolate(), owner_window());
Expand Down Expand Up @@ -1976,6 +1984,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
.SetMethod("_getZoomFactor", &WebContents::GetZoomFactor)
.SetMethod("getType", &WebContents::GetType)
.SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
.SetMethod("getLastWebPreferences", &WebContents::GetLastWebPreferences)
.SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow)
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
.SetMethod("unregisterServiceWorker",
Expand Down
1 change: 1 addition & 0 deletions atom/browser/api/atom_api_web_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ class WebContents : public mate::TrackableObject<WebContents>,

// Returns the web preferences of current WebContents.
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate);
v8::Local<v8::Value> GetLastWebPreferences(v8::Isolate* isolate);

// Returns the owner window.
v8::Local<v8::Value> GetOwnerBrowserWindow();
Expand Down
38 changes: 38 additions & 0 deletions atom/browser/web_contents_preferences.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,28 @@ WebContentsPreferences::WebContentsPreferences(
web_contents->SetUserData(UserDataKey(), base::WrapUnique(this));

instances_.push_back(this);

// Set WebPreferences defaults onto the JS object
SetDefaultBoolIfUndefined("plugins", false);
SetDefaultBoolIfUndefined(options::kExperimentalFeatures, false);
SetDefaultBoolIfUndefined(options::kExperimentalCanvasFeatures, false);
bool node = SetDefaultBoolIfUndefined(options::kNodeIntegration, true);
SetDefaultBoolIfUndefined(options::kNodeIntegrationInWorker, false);
SetDefaultBoolIfUndefined(options::kWebviewTag, node);
SetDefaultBoolIfUndefined("sandbox", false);
SetDefaultBoolIfUndefined("nativeWindowOpen", false);
SetDefaultBoolIfUndefined(options::kContextIsolation, false);
SetDefaultBoolIfUndefined("javascript", true);
SetDefaultBoolIfUndefined("images", true);
SetDefaultBoolIfUndefined("textAreasAreResizable", true);
SetDefaultBoolIfUndefined("webgl", true);
SetDefaultBoolIfUndefined("webSecurity", true);
SetDefaultBoolIfUndefined("allowRunningInsecureContent", false);
#if defined(OS_MACOSX)
SetDefaultBoolIfUndefined(options::kScrollBounce, false);
#endif
SetDefaultBoolIfUndefined("offscreen", false);
last_web_preferences_.MergeDictionary(&web_preferences_);
}

WebContentsPreferences::~WebContentsPreferences() {
Expand All @@ -56,6 +78,16 @@ WebContentsPreferences::~WebContentsPreferences() {
instances_.end());
}

bool WebContentsPreferences::SetDefaultBoolIfUndefined(const std::string key,
bool val) {
bool existing;
if (!web_preferences_.GetBoolean(key, &existing)) {
web_preferences_.SetBoolean(key, val);
return val;
}
return existing;
}

void WebContentsPreferences::Merge(const base::DictionaryValue& extend) {
web_preferences_.MergeDictionary(&extend);
}
Expand All @@ -80,6 +112,12 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(

base::DictionaryValue& web_preferences = self->web_preferences_;

// We are appending args to a webContents so let's save the current state
// of our preferences object so that during the lifetime of the WebContents
// we can fetch the options used to initally configure the WebContents
self->last_web_preferences_.Clear();
self->last_web_preferences_.MergeDictionary(&web_preferences);

bool b;
// Check if plugins are enabled.
if (web_preferences.GetBoolean("plugins", &b) && b)
Expand Down
7 changes: 7 additions & 0 deletions atom/browser/web_contents_preferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,24 @@ class WebContentsPreferences

// Returns the web preferences.
base::DictionaryValue* web_preferences() { return &web_preferences_; }
base::DictionaryValue* last_web_preferences() {
return &last_web_preferences_;
}

private:
friend class content::WebContentsUserData<WebContentsPreferences>;

// Set preference value to given bool if user did not provide value
bool SetDefaultBoolIfUndefined(const std::string key, bool val);

// Get preferences value as integer possibly coercing it from a string
bool GetInteger(const std::string& attributeName, int* intValue);

static std::vector<WebContentsPreferences*> instances_;

content::WebContents* web_contents_;
base::DictionaryValue web_preferences_;
base::DictionaryValue last_web_preferences_;

DISALLOW_COPY_AND_ASSIGN(WebContentsPreferences);
};
Expand Down
4 changes: 2 additions & 2 deletions lib/browser/guest-view-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,15 +156,15 @@ const createGuest = function (embedder, params) {
// Forward internal web contents event to embedder to handle
// native window.open setup
guest.on('-add-new-contents', (...args) => {
if (guest.getWebPreferences().nativeWindowOpen === true) {
if (guest.getLastWebPreferences().nativeWindowOpen === true) {
const embedder = getEmbedder(guestInstanceId)
if (embedder != null) {
embedder.emit('-add-new-contents', ...args)
}
}
})
guest.on('-web-contents-created', (...args) => {
if (guest.getWebPreferences().nativeWindowOpen === true) {
if (guest.getLastWebPreferences().nativeWindowOpen === true) {
const embedder = getEmbedder(guestInstanceId)
if (embedder != null) {
embedder.emit('-web-contents-created', ...args)
Expand Down
8 changes: 4 additions & 4 deletions lib/browser/guest-window-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ const mergeBrowserWindowOptions = function (embedder, options) {
mergeOptions(options, parentOptions)
} else {
// Or only inherit webPreferences if it is a webview.
mergeOptions(options.webPreferences, embedder.getWebPreferences())
mergeOptions(options.webPreferences, embedder.getLastWebPreferences())
}

// Inherit certain option values from parent window
for (const [name, value] of inheritedWebPreferences) {
if (embedder.getWebPreferences()[name] === value) {
if (embedder.getLastWebPreferences()[name] === value) {
options.webPreferences[name] = value
}
}
Expand Down Expand Up @@ -177,8 +177,8 @@ const getGuestWindow = function (guestContents) {
// The W3C does not have anything on this, but from my understanding of the
// security model of |window.opener|, this should be fine.
const canAccessWindow = function (sender, target) {
return (target.getWebPreferences().openerId === sender.id) ||
(sender.getWebPreferences().nodeIntegration === true) ||
return (target.getLastWebPreferences().openerId === sender.id) ||
(sender.getLastWebPreferences().nodeIntegration === true) ||
isSameOrigin(sender.getURL(), target.getURL())
}

Expand Down
2 changes: 1 addition & 1 deletion lib/renderer/security-warnings.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const getWebPreferences = function () {
}

const { remote } = require('electron')
webPreferences = remote.getCurrentWebContents().getWebPreferences()
webPreferences = remote.getCurrentWebContents().getLastWebPreferences()
return webPreferences
} catch (error) {
return null
Expand Down
2 changes: 1 addition & 1 deletion spec/api-browser-window-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2999,7 +2999,7 @@ describe('BrowserWindow module', () => {
})
it('enables context isolation on child windows', (done) => {
app.once('browser-window-created', (event, window) => {
assert.equal(window.webContents.getWebPreferences().contextIsolation, true)
assert.equal(window.webContents.getLastWebPreferences().contextIsolation, true)
done()
})
w.loadURL(`file://${fixtures}/pages/window-open.html`)
Expand Down
26 changes: 23 additions & 3 deletions spec/chromium-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,26 @@ describe('chromium feature', () => {
b = window.open(windowUrl, '', 'nodeIntegration=no,show=no')
})

it('disables webviewTag when node integration is disabled on the parent window', (done) => {
let b
listener = (event) => {
assert.equal(event.data.isWebViewUndefined, true)
b.close()
done()
}
window.addEventListener('message', listener)

const windowUrl = require('url').format({
pathname: `${fixtures}/pages/window-opener-no-web-view-tag.html`,
protocol: 'file',
query: {
p: `${fixtures}/pages/window-opener-web-view.html`
},
slashes: true
})
b = window.open(windowUrl, '', 'nodeIntegration=no,show=no')
})

it('disables node integration when it is disabled on the parent window for chrome devtools URLs', (done) => {
let b
app.once('web-contents-created', (event, contents) => {
Expand All @@ -287,7 +307,7 @@ describe('chromium feature', () => {
app.once('web-contents-created', (event, contents) => {
contents.once('did-finish-load', () => {
app.once('browser-window-created', (event, window) => {
const preferences = window.webContents.getWebPreferences()
const preferences = window.webContents.getLastWebPreferences()
assert.equal(preferences.javascript, false)
window.destroy()
b.close()
Expand Down Expand Up @@ -509,7 +529,7 @@ describe('chromium feature', () => {
done()
}
window.addEventListener('message', listener)
w = window.open(url, '', 'show=no')
w = window.open(url, '', 'show=no,nodeIntegration=no')
})

it('works when origin matches', (done) => {
Expand All @@ -518,7 +538,7 @@ describe('chromium feature', () => {
done()
}
window.addEventListener('message', listener)
w = window.open(`file://${fixtures}/pages/window-opener-location.html`, '', 'show=no')
w = window.open(`file://${fixtures}/pages/window-opener-location.html`, '', 'show=no,nodeIntegration=no')
})

it('works when origin does not match opener but has node integration', (done) => {
Expand Down
15 changes: 15 additions & 0 deletions spec/fixtures/pages/window-opener-no-web-view-tag.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<html>
<body>
<script type="text/javascript" charset="utf-8">
var windowUrl = decodeURIComponent(window.location.search.substring(3))
var opened = window.open('file://' + windowUrl, '', 'webviewTag=yes,show=no')
window.addEventListener('message', function (event) {
try {
opened.close()
} finally {
window.opener.postMessage(event.data, '*')
}
})
</script>
</body>
</html>
9 changes: 9 additions & 0 deletions spec/fixtures/pages/window-opener-web-view.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<html>
<body>
<script type="text/javascript" charset="utf-8">
window. => {
window.opener.postMessage({isWebViewUndefined: typeof WebView === 'undefined'}, '*')
}
</script>
</body>
</html>
0